代码之家  ›  专栏  ›  技术社区  ›  Trident D'Gao

在TypeScript中删除子属性的接口的一种方法

  •  0
  • Trident D'Gao  · 技术社区  · 6 年前

    说我有

    interface A {
        b: {
             c: {
                  d: string;
                  e: number;
             }
        }
    }
    

    我想得到接口 A_no_E 它的接口与 A 但是 没有 A.b.c.e

    interface A_no_E {
        b: {
             c: {
                  d: string;
             }
        }
    }
    

    通过高级类型的打字脚本 不用一个道具一个道具地重新申报 ?

    2 回复  |  直到 6 年前
        1
  •  2
  •   jcalz    6 年前

    嗯,我想你可以申报你自己的 DeepOmit mapped conditional

    // Tail removes the first element from a tuple type
    // so Tail<[string, number, boolean]> is [number, boolean]
    type Tail<L extends any[]> =
      ((...l: L) => void) extends ((h: infer H, ...t: infer T) => void) ? T : never;
    
    
    type DeepOmit<T, K extends Array<keyof any>> =
      K extends [] ? T : K extends [infer P] ? Pick<T, Exclude<keyof T, P>> : {
        [P in keyof T]: P extends K[0] ? DeepOmit<T[P], Tail<K>> : T[P]
      }
    

    然后你就可以做了

    type A_no_E = DeepOmit<A, ['b', 'c', 'e']>;
    

    如果您使用IntelliSense,它的计算结果会有点难看

    type A_no_E = {
        b: {
            c: Pick<{
                d: string;
                e: number;
            }, "d">;
        };
    }
    

    这相当于您想要的:

    declare const a_no_e: A_no_E
    a_no_e.b.c.d; // string
    a_no_e.b.c.e; // error, property e does not exist
    

    编辑:的替代定义 深奥 这就产生了一种不那么丑陋的智能感觉:

    type Tail<L extends any[]> =
      ((...l: L) => void) extends ((h: infer H, ...t: infer T) => void) ? T : never;
    type DeepOmit<T, K extends Array<keyof any>, KT extends keyof T = Exclude<keyof T, K[0]>> =
      K extends [] ? T : K extends [infer P] ? { [Q in KT]: T[Q] } : {
        [P in keyof T]: P extends K[0] ? DeepOmit<T[P], Tail<K>> : T[P]
      }
    

    现在 A_no_E 在IntelliSense中显示为:

    type A_no_E = {
        b: {
            c: {
                d: string;
            };
        };
    }
    

    希望有帮助。

        2
  •  0
  •   adz5A    6 年前

    example . 其思想是将指定路径上不接受值的类型与原始类型相交 A .