Deep Omit with typescript

后端 未结 3 619
梦谈多话
梦谈多话 2020-12-11 03:46

Is it possible to maintain type coverage on a function that deeply removes all instances of a key in an object?

My function looks like this.

function         


        
3条回答
  •  独厮守ぢ
    2020-12-11 04:24

    This can easily be done, you just need to use mapped types to recurse down the properties:

    type Primitive = string | Function | number | boolean | Symbol | undefined | null 
    type DeepOmitHelper = {
        [P in K]: //extra level of indirection needed to trigger homomorhic behavior 
            T[P] extends infer TP ? // distribute over unions
            TP extends Primitive ? TP : // leave primitives and functions alone
            TP extends any[] ? DeepOmitArray : // Array special handling
            DeepOmit 
            : never
    }
    type DeepOmit = T extends Primitive ? T : DeepOmitHelper> 
    
    type DeepOmitArray = {
        [P in keyof T]: DeepOmit
    }
    type Input =  {
        __typename: string,
        a: string,
        nested: {
            __typename: string,
            b: string
        }
        nestedArray: Array<{
            __typename: string,
            b: string
        }>
        nestedTuple: [{
            __typename: string,
            b: string
        }]
    }
    
    type InputWithoutKey = DeepOmit
    
    let s: InputWithoutKey = {
        a: "",
        nested: {
            b:""
        },
        nestedArray: [
            {b: ""}
        ],
        nestedTuple: [
            { b: ""},
        ]
    }
    

    Just a caveat, this works on 3.4, the handling of mapped types on arrays and tuples has changed recently, so depending on version you might need to handle arrays as a special case.

提交回复
热议问题