TypeScript Type-safe Omit Function

前端 未结 4 1837
余生分开走
余生分开走 2021-02-08 20:00

I want to replicate lodash\'s _.omit function in plain typescript. omit should return an object with certain properties removed specified via parameter

4条回答
  •  囚心锁ツ
    2021-02-08 20:37

    interface Omit {
        
        (obj: T, ...keys: K): {
            [K2 in Exclude]: T[K2]
        }
    }
    
    const omit: Omit = (obj, ...keys) => {
        const ret = {} as {
            [K in keyof typeof obj]: (typeof obj)[K]
        };
        let key: keyof typeof obj;
        for (key in obj) {
            if (!(keys.includes(key))) {
                ret[key] = obj[key];
            }
        }
        return ret;
    };
    

    For convenience I've pulled most of the typings to an interface.

    The problem was that K had been being inferred as a tuple, not as a union of keys. Hence, I changed it's type constraint accordingly:

    [...(keyof T)[]] // which can be broke down to:
    keyof T // a union of keys of T
    (keyof T)[] // an array containing keys of T
    [...X] // a tuple that contains X (zero or more arrays like the  described one above)
    

    Then, we need to transform the tuple K to a union (in order to Exclude it from keyof T). It is done with K[number], which is I guess is self-explaining, it's the same as T[keyof T] creating a union of values of T.

    Playground

提交回复
热议问题