Odpowiedzi:
W języku TypeScript 3.5 Omittyp został dodany do biblioteki standardowej. Zobacz przykłady poniżej, aby dowiedzieć się, jak go używać.
W TypeScript 2.8 Excludetyp został dodany do standardowej biblioteki, co pozwala na zapisanie typu pominięcia po prostu jako:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
Nie możesz używać Excludetypu w wersjach poniżej 2.8, ale możesz utworzyć dla niego zamiennik, aby użyć tego samego rodzaju definicji, co powyżej. Jednak to zastąpienie będzie działać tylko dla typów ciągów, więc nie jest tak potężne jak Exclude.
// Functionally the same as Exclude, but for strings only.
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>
I przykład tego typu w użyciu:
interface Test {
a: string;
b: number;
c: boolean;
}
// Omit a single property:
type OmitA = Omit<Test, "a">; // Equivalent to: {b: number, c: boolean}
// Or, to omit multiple properties:
type OmitAB = Omit<Test, "a"|"b">; // Equivalent to: {c: boolean}
Omit<{a?: string, b?: boolean}, "b">wyniki w {a: string | undefined}, który nadal akceptuje undefinedjako wartość, ale traci opcjonalny modyfikator on a. :(
Pickile widzę.
Omitróżni się od podanej tutaj. W standardowym bibliotece jest to type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;Zmiana, choć niewielka, wywołała dyskusję , więc bądź świadomy różnicy.
W przypadku maszynopisu 2.8 można użyć nowego typu wbudowanego Exclude. Informacje o wersji 2.8 faktycznie wspominają o tym w sekcji „Wstępnie zdefiniowane typy warunkowe”:
Uwaga: Typ Exclude jest poprawną implementacją sugerowanego tutaj typu Diff. […] Nie uwzględniliśmy typu Pomiń, ponieważ jest on napisany trywialnie jako
Pick<T, Exclude<keyof T, K>>.
Stosując to do twojego przykładu, typ XY można zdefiniować jako:
type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>
Znalazłem rozwiązanie polegające na zadeklarowaniu niektórych zmiennych i użyciu operatora spreadu do wnioskowania typu:
interface XYZ {
x: number;
y: number;
z: number;
}
declare var { z, ...xy }: XYZ;
type XY = typeof xy; // { x: number; y: number; }
Działa, ale byłbym zadowolony, gdyby znalazł lepsze rozwiązanie.
typeofjest jedną z bardziej niedocenianych cech maszynopisu.
type Smth = XY & { z: string };?
Jeśli wolisz korzystać z biblioteki, użyj ts-essentials .
import { Omit } from "ts-essentials";
type ComplexObject = {
simple: number;
nested: {
a: string;
array: [{ bar: number }];
};
};
type SimplifiedComplexObject = Omit<ComplexObject, "nested">;
// Result:
// {
// simple: number
// }
// if you want to Omit multiple properties just use union type:
type SimplifiedComplexObject = Omit<ComplexObject, "nested" | "simple">;
// Result:
// { } (empty type)
PS: Znajdziesz tam wiele innych przydatnych rzeczy;)
Począwszy od Typescript 3.5, zostanie dołączony pomocnik Omit : TypeScript 3.5 RC - Typ pomocnika Omit
Możesz go użyć bezpośrednio, a podczas aktualizacji powinieneś usunąć własną definicję pomocnika Omit.
W maszynie 3.5+ :
interface TypographyProps {
variant: string
fontSize: number
}
type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">
Lubię to:
interface XYZ {
x: number;
y: number;
z: number;
}
const a:XYZ = {x:1, y:2, z:3};
const { x, y, ...last } = a;
const { z, ...firstTwo} = a;
console.log(firstTwo, last);
Diff<T, U>(z typami dostępnymi dla kluczyTiUjako typy) jakoTpodzbiór z kluczem przecięcia 3 typów: wpisz klucz taki sam jak wartość dlaT, wpiszneverforUi wpisz zneverdla wszystkich kluczy. Następnie przekazujesz go przez indeksator, aby uzyskać prawidłowe typy wartości. Czy mam rację?