我目前正在尝试编写一个更高阶的函数without
,该函数将返回一个新对象,而不将键传递给返回的函数。
我看不出有什么方法可以让reducer中的密钥为keyof T
,因为Object.keys
返回的是string[]
而不是Array<keyof T>
,如果它返回了,我认为它会解决这个问题。我是不是在这里的类型中遗漏了一些可以解决这个问题的明显内容?
const without = <T>(object: T) => (...parts: Array<keyof T>) => {
return Object.keys(object).reduce((acc, key) => {
// `key` is of type `string` not `keyof T`
if (!parts.includes(key)) {
acc[key] = object[key];
}
return acc;
}, {} as Omit<T, typeof parts[number]>);
};
const obj = { a: 1, b: 2, c: 3 };
const result = without(obj)('a', 'c');
TS游乐场
Object.keys
将返回string[]
,原因如下。您需要使用类型断言来实现这一点。
const without = <T>(object: T) => <K extends keyof T>(...parts: Array<K>): Omit<T, K> => {
return (Object.keys(object) as Array<keyof T>).reduce((acc, key) => {
if (!parts.includes(key as any)) {
acc[key] = object[key];
}
return acc;
}, {} as T);
};
const obj = { a: 1, b: 2, c: 3 };
const result = without(obj)('a', 'c');
游乐场链接
除了断言为Array<keyof T>
之外,我还将reduce
的初始值的类型更改为T
。这是为了允许分配acc[key] = object[key]
。T[keyof T]
将可分配给自身,但Omit<T, typeof parts[number]>[keyof T]
将不可分配。T
将依次被分配给Omit<T, typeof parts[number]>