我想用普通的typescript复制lodash的_.omit
函数。omit
应该返回一个对象,其中某些属性被删除,这些属性是通过位于第一个对象参数之后的参数指定的。
下面是我的最佳尝试:
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;
}
这会产生以下错误:
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
我的错误解释是:
1.因为key是keyof T
,而T
是一个对象,所以key可以是symbol
、number
或string
。
1.因为我使用了for in
循环,key只能是string
,但是如果我传入一个数组,includes
可能会接受一个number
,我想,这意味着这里有一个类型错误吗?
任何见解,为什么这不工作,以及如何使它的工作是赞赏!
8条答案
按热度按时间3zwtqj6y1#
为了方便起见,我把大部分的输入都拉到了一个界面上。
问题是
K
被推断为一个 tuple,而不是键的 union,因此我相应地修改了它的类型约束:然后,我们需要把元组
K
转换成一个并集(为了把keyof T
转换成Exclude
),这是用K[number]
完成的,我想这是不言自明的,这和T[keyof T]
创建T
的值的并集是一样的。Playground
dwbf0jvd2#
最简单的办法:
作为纯函数:
h5qlskok3#
上面Nurbol给出的公认答案可能是类型化程度更高的版本,但下面是我在
utils-min
中所做的事情。它使用了内置的类型脚本Omit,并且被设计成只支持字符串键名。(仍然需要放松Set to Set,但是其他的一切看起来都很好地工作)
kwvwclae4#
Object.keys
或for in
将键作为字符串返回,并排除符号。数字键也将转换为字符串。您需要将数字字符串键转换为数字,否则它将返回带有字符串键的对象。
要包含符号,可以使用下面的代码。
unguejic5#
不确定我是否得到了一个点,但我遇到了类似的问题,我想确保我没有错字时,省略属性,所以我来到这样的解决方案:
tsc不允许您忽略Person接口上不存在的属性
dfuffjeb6#
如果我们将键的类型限制为string [],它可以工作。但这似乎不是一个好主意。键应该是string|号码|符号[];
ipakzgxi7#
不幸的是,不可能摆脱
as any
Playground
3htmauhk8#
使用数组
reduce
方法省略该道具。