Antworten:
In TypeScript 3.5 wurde der Omit
Typ zur Standardbibliothek hinzugefügt. In den folgenden Beispielen finden Sie Informationen zur Verwendung.
In TypeScript 2.8 wurde der Exclude
Typ zur Standardbibliothek hinzugefügt, sodass ein Auslassungstyp einfach wie folgt geschrieben werden kann:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
Sie können den Exclude
Typ nicht in Versionen unter 2.8 verwenden, aber Sie können einen Ersatz dafür erstellen, um dieselbe Definition wie oben zu verwenden. Diese Ersetzung funktioniert jedoch nur für Zeichenfolgentypen und ist daher nicht so leistungsfähig wie 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>>
Und ein Beispiel für diesen Typ:
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">
ergibt sich {a: string | undefined}
, was immer noch undefined
als Wert akzeptiert , aber den optionalen Modifikator ein verliert a
. :(
Pick
soweit ich sehen kann, buchstäblich mit der Typdefinition identisch war .
Omit
von der hier angegebenen unterscheidet. In der stdlib ist es type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Die Änderung, obwohl geringfügig, hat einige Debatten ausgelöst , seien Sie sich also des Unterschieds bewusst.
Mit Typoskript 2.8 können Sie den neuen integrierten Exclude
Typ verwenden. In den Versionshinweisen zu 2.8 wird dies im Abschnitt "Vordefinierte bedingte Typen" erwähnt:
Hinweis: Der Exclude-Typ ist eine ordnungsgemäße Implementierung des hier vorgeschlagenen Diff-Typs. [...] Wir haben den Omit-Typ nicht aufgenommen, da er trivial als geschrieben ist
Pick<T, Exclude<keyof T, K>>
.
Wenn Sie dies auf Ihr Beispiel anwenden, kann der Typ XY wie folgt definiert werden:
type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>
Ich habe eine Lösung gefunden , indem ich einige Variablen deklariert und den Spread-Operator verwendet habe, um auf den Typ zu schließen:
interface XYZ {
x: number;
y: number;
z: number;
}
declare var { z, ...xy }: XYZ;
type XY = typeof xy; // { x: number; y: number; }
Es funktioniert, aber ich würde mich über eine bessere Lösung freuen.
typeof
ist eines der am meisten unterschätzten Merkmale von Typoskript.
type Smth = XY & { z: string };
?
Wenn Sie eine Bibliothek bevorzugen, verwenden Sie 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: Dort findest du viele andere nützliche Dinge;)
Ab Typescript 3.5 ist der Omit-Helfer enthalten: TypeScript 3.5 RC - Der Omit-Helfer-Typ
Sie können es direkt verwenden und sollten beim Aktualisieren Ihre eigene Definition des Omit-Hilfsprogramms entfernen.
In Typescript 3.5+ :
interface TypographyProps {
variant: string
fontSize: number
}
type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">
Das gefällt mir:
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>
(mitT
undU
als für Schlüssel verfügbare Typen) alsT
Teilmenge einer Schnittmenge von 3 Typen mit Schlüssel: Typ mit Schlüssel, der dem Wert für entsprichtT
, Typ mitnever
fürU
und Typ mitnever
für alle Schlüssel. Dann übergeben Sie es durch den Indexer, um die richtigen Wertetypen zu erhalten. Habe ich recht?