TypeScript Type-safe Omit函数

Sal*_*ami 7 javascript underscore.js typescript lodash ecmascript-7

我想_.omit在普通打字稿中复制lodash的功能.omit应返回一个对象,该对象具有在首先出现的object参数之后通过参数指定的某些属性.

这是我最好的尝试:

function omit<T extends object, K extends keyof T>(obj: T, ...keys: K[]): {[k in Exclude<keyof T, K>]: T[k]} {
    let ret: any = {};
    let key: keyof T;
    for (key in obj) {
        if (!(keys.includes(key))) {
            ret[key] = obj[key];
        }
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

这给了我这个错误:

Argument of type 'keyof T' is not assignable to parameter of type 'K'.
  Type 'string | number | symbol' is not assignable to type 'K'.
    Type 'string' is not assignable to type 'K'.ts(2345)
let key: keyof T
Run Code Online (Sandbox Code Playgroud)

我对错误的解释是:

  1. 由于密钥是keyof TT是一个对象,密钥可以是一个symbol,numberstring.

  2. 因为我使用for in循环,所以key只能是a,string但是如果我传入一个数组,includes可能需要一个number,例如?我认为.这意味着这里有类型错误?

任何有关为什么这不起作用以及如何使其工作的见解表示赞赏!

90d*_*0dy 10

最简单的方法:

export const omit = <T extends object, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> => {
  keys.forEach((key) => delete obj[key])
  return obj
}
Run Code Online (Sandbox Code Playgroud)

作为纯函数:

export const omit = <T extends object, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> => {
  const _ = { ...obj }
  keys.forEach((key) => delete _[key])
  return _
}
Run Code Online (Sandbox Code Playgroud)


Nur*_*yev 5

interface Omit {
    <T extends object, K extends [...(keyof T)[]]>
    (obj: T, ...keys: K): {
        [K2 in Exclude<keyof T, K[number]>]: T[K2]
    }
}

const omit: Omit = (obj, ...keys) => {
    let 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;
}
Run Code Online (Sandbox Code Playgroud)

为了方便起见,我将大多数输入拉到了界面上。

问题K在于(正确的时态?)被推断为元组,而不是键的并集。因此,我相应地更改了它的类型约束:

[...(keyof T)[]] // which can be broke down to:
keyof T // a union of keys of T
(keyof T)[] // an array containing keys of T
[] // a tuple
[...X] // a tuple that contains an array X
Run Code Online (Sandbox Code Playgroud)

然后,我们需要将元组K转换为并集(以便Excludekeyof T)。它完成了K[number],我想这是不言而喻的,它与T[keyof T]创建的值的并集相同T

操场