【发布时间】:2020-08-30 09:21:57
【问题描述】:
以下函数workOnFunctions 接受一个对象和该对象的键数组,其中所有键都映射到一个函数:
const myObj = {
a: () => 1,
b: "test",
c: 2,
d: (a : number) => a*2
}
function workOnFunctions <K extends PropertyKey>(o: Record<K, Function>, names: K[]) {
names.forEach(name => {
const f = o[name]; // do something with function f
})
}
我注意到当我这样做时它按预期工作:
workOnFunctions(myObj, ["a", "d"]); // works
但是当将数组存储在一个变量中,然后将该变量传递给函数时,我得到了错误
Argument of type '{ a: () => number; b: string; c: number; d: (a: number) => number; }' is not assignable to parameter of type 'Record<string, Function>'.
Property 'b' is incompatible with index signature.
Type 'string' is not assignable to type 'Function'.
代码:
const names = ["a", "d"];
workOnFunctions(myObj, names);
为什么会这样?似乎编译器无法正确推断 names 的类型。当我直接传递数组时,它可以。我也试过这个:
const names = ["a", "d"] as const;
workOnFunctions(myObj, names);
这也不起作用。
我的最终目标是编写一个函数,该函数接受一个对象和一组指向该对象内函数的键。
编辑:找到部分解决方案,但我不明白为什么
看起来这样可行:
type KeysMatching<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T]
const names : Array<KeysMatching<typeof myObj, Function>> = ["a", "d"];
workOnFunctions(myObj, names);
我从这里得到KeysMatching:TypeScript: Accept all Object keys that map to a specific type
但是为什么我直接传递数组时编译器可以自己推断出这种复杂类型呢?使用单独的数组时是否也有自动推断类型的技巧?
【问题讨论】:
标签: typescript types