我有一个映射类型 Minus<A,B>
用于创建具有 A 上所有属性的类型,但 B 上的属性除外,定义如下:
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]};
例如,如果我有两个接口(interface),A
interface A {
thing1: string;
thing2: number;
}
和B
interface B {
thing1: string;
}
然后 Minus<A, B>
应该产生等同于
interface C {
thing2: number;
}
在我在 A 上有可选类型之前,这很有效,因为这些在途中某处丢失了。
替换 A
与
interface A {
thing1: string;
thing2?: number;
}
将导致一个看起来像的类型
interface C {
thing2: number;
}
而不是想要的
interface C {
thing2?: number;
}
有趣的是,Readonly<T>
的行为似乎确实保留了属性是否可选; Readonly 将产生一个等同于
interface ReadonlyA {
readonly thing1: string;
readonly thing2?: number;
}
所以我怀疑这与我的 Diff 类型有关。
有没有人有一个解决方案可以在 A
上保留属性是否可选? ?
最佳答案
解决方案是重新定义 Minus<A, B>
成为
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>>;
这将正确保留可选类型。
归功于 Daniel Khoroshko为我指出正确的方向
关于typescript - 为什么我会丢失属性在此映射类型中是否可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47899627/