考虑以下简化函数,该函数接受一个对象和该对象的属性,并返回仅具有指定属性的该对象的克隆:
export function clonePick<T, K extends keyof T>(obj: T, prop: K) {
const keys = Object.keys(obj).filter(k => k === prop)
return keys.reduce(
(clone: any, key: string) => {
return { ...clone, [key]: obj[key as keyof T] };
},
{}
);
}
除了值而不是类型之外,这与Pick基本上是相同的行为,因此它的返回类型可以表示为:
Pick<T, prop>
除上述无效的打字稿外。但是,调用函数时,我们可以在运行时知道prop well 的值:
interface ITest {
numProp: number;
strProp: string;
}
const test = { numProp: 1, strProp: '1' }; // <-- type is ITest
const testClone = clonePick(test, 'numProp') // <-- type is any
我可以轻松地明确声明这一点:
const testClone: Pick<ITest, 'numProp'> = clonePick(test, 'numProp')
但是,如果我可以将该行为作为上述功能的一部分,它将具有更大的可维护性。这可能吗?最好它可以使用一系列属性以及单个道具
答案 0 :(得分:1)
您不会让编译器推断对reduce
的复杂Pick
调用,甚至对于{ [prop]: obj[prop] }
之类的简单事情也不会。最好的选择是对函数的返回类型使用注释。
export function clonePick<T, K extends keyof T>(obj: T, prop: K): Pick<T,K> {
return { [prop]: obj[prop] } as any;
}
interface ITest {
numProp: number;
strProp: string;
}
const test = { numProp: 1, strProp: '1' }; // <-- type is ITest
const testClone = clonePick(test, 'numProp') //
testClone.numProp
testClone.strProp // err