typescript - Varför förlorar jag information om huruvida en egenskap är valfri i denna Mapped Type
Jag har en mappad typ Minus<A,B> för att skapa en typ med alla egenskaper på A förutom de som också finns på B, som definieras som följer:
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
/**
* Type T without any of the properties on U.
*/
export type Minus<T, U> = {[P in Diff<keyof T, keyof U>]: T[P]};
Till exempel, om jag har två gränssnitt, A
interface A {
thing1: string;
thing2: number;
}
och B
interface B {
thing1: string;
}
då Minus<A, B> bör resultera i en typ motsvarande
interface C {
thing2: number;
}
Detta fungerar bra tills jag har valfria typer på A, eftersom dessa går förlorade någonstans på vägen.
Ersätter A med
interface A {
thing1: string;
thing2?: number;
}
kommer att resultera i en typ som ser ut som
interface C {
thing2: number;
}
istället för det önskade
interface C {
thing2?: number;
}
Intressant nog verkar beteendet för en Readonly<T> bevara huruvida egenskaper är valfria eller inte; Readonly kommer att producera en typ som motsvarar
interface ReadonlyA {
readonly thing1: string;
readonly thing2?: number;
}
Så jag misstänker att detta har något att göra med min Diff-typ.
Har någon en lösning som kommer att behålla om egenskaper är valfria eller inte på A?
Svar #1
Lösningen var att omdefiniera Minus<A, B> till att vara
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
/**
* Type T without any of the properties on U.
*/
export type Minus<T, U> = Pick<T, Diff<keyof T, keyof U>>;
Vilket korrekt kommer att behålla valfria typer.
Beröm till Daniel Khoroshko för att ha pekat mig i rätt riktning
