Typescript Typ 'never': wie man ihn für Objektfelder verwendet?
Ich versuche, dieses Beispiel so zum Laufen zu bringen:
interface Foo {
a: number;
b: string;
c: boolean;
}
type Explode<T> = keyof T extends infer K
? K extends unknown
? { [I in keyof T]: I extends K ? T[I] : never }
: never
: never;
type Test = Explode<Foo>;
const test: Test = {a: 1};
was mir den folgenden Fehler gibt:
Type '{ a: number; }' is not assignable to type '{ a: number; b: never; c: never; } | { a: never; b: string; c: never; } | { a: never; b: never; c: boolean; }'.
Type '{ a: number; }' is missing the following properties from type '{ a: number; b: never; c: never; }': b, c
Wie kann ich ein Objekt vom Typ Test erstellen, ohne den Fehler zu bekommen? Ich möchte einen Typ, der entweder das Feld a oder b oder c enthalten kann (oder ein leeres {} sein kann).
Antwort #1
Ich habe die Lösung gefunden. Ich musste die Felder von Foo optional machen, so wie folgt:
BEARBEITET, um den Vorschlag von @apokryfos zu berücksichtigen
interface Foo {
a: number;
b: string;
c: boolean;
}
Jetzt kann ich:
interface Foo {
a: number;
b: string;
c: boolean;
}
type AtMostOneOf<T> = keyof T extends infer K
? K extends unknown
? { [I in keyof T]+?: I extends K ? T[I] : never }
: never
: never;
type Test = AtMostOneOf<Foo>;
const test: Test = {a: 1}; // allowed
const test1: Test = {b: 'asd'}; // allowed
const test2: Test = {a: 1, b: 'asd'}; // not allowed
const test3: Test = {} // allowed
Spielplatz
Antwort #2
Sie können den Explode-Typ definieren als:
type Explode<T> = {
[K in keyof T]: {
[key in K]: T[K]
}
}[keyof T]
dann wird type Test zu:
type Test = {
a: number;
} | {
b: string;
} | {
c: boolean;
}
TS-Spielplatz
