代码之家  ›  专栏  ›  技术社区  ›  Ran Lottem

Typescript-有些省略实现从属性中移除可选性

  •  0
  • Ran Lottem  · 技术社区  · 6 年前

    Omit 省略 本身。我的理解有点困难 为什么有些实现是同态的,而有些则不是

    我发现:

    • 悬停时显示的实现 省略 不是正确的
    • 悬停时显示的实现 省略

    这是我的代码:

    // a type with optional and readonly properties
    type HasOptional = { a: number; b?: number, c: string; d?: readonly string[]; };
    
    // first attempt
    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
    
    // Omit's 'fake' implementation, as shown by Intellisense
    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
    
    // Using Omit itself
    type Omit_3<T, K extends string | number | symbol> = Omit<T, K>;
    type Omit_3_Optional = Omit_3<HasOptional, 'a'>; // optionality maintained!
    
    // Writing Omit's implementation explicitly
    type Omit_4<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
    type Omit_4_Optional = Omit_4<HasOptional, 'a'>; // optionality maintained!
    

    here, in an answer about deep Omit [P in K]: 被用作额外的间接级别,以导致同态行为,但这也存在于这里,但前两个实现并没有保留“可选性”。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    6 年前

    映射类型在两种情况下被认为是同态的。要么我们画一张地图 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!
    
    推荐文章