映射类型在两种情况下被认为是同态的。要么我们画一张地图
keyof T
(
docs
)或者我们映射一个类型参数
K
哪里
有一个约束
T键
(
K extends keyof T
,
docs
当
Exclude<keyof T, K>
不适用于这两种特定情况。这意味着直接映射到
不会生成同态映射类型。如果我们采取
并将其放入具有所需约束的类型参数中,然后我们获得所需的行为。
// a type with optional and readonly properties
type HasOptional = { a: number; b?: number, c: string; d?: readonly string[]; };
// mapping over Exclude<keyof T, K> optionality lost
type Omit_1<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P]; };
type Omit_1_Optional = Omit_1<HasOptional, 'a'>; // b, d lost optionality
// mapping over Exclude<keyof T, K> optionality lost
type Omit_2<T, K extends string | number | symbol> = { [P in Exclude<keyof T, K>]: T[P]; };
type Omit_2_Optional = Omit_2<HasOptional, 'a'>; // b, d lost optionality
// Omit in 3.5 has homomorphic behavior since it uses Pick which is homomorphic
type Omit_3<T, K extends string | number | symbol> = Omit<T, K>;
type Omit_3_Optional = Omit_3<HasOptional, 'a'>; // optionality maintained!
// has homomorphic behavior since it uses Pick which is homomorphic
type Omit_4<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Omit_4_Optional = Omit_4<HasOptional, 'a'>; // optionality maintained!