以下函数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
但是,当我直接传递数组时,为什么编译器可以自行推断这种复杂类型呢?使用单独的数组时,是否还有技巧自动推断类型?
答案 0 :(得分:0)
您的错误不是由于names
数组,而是由于您的myObject
,
“ b”和“ c”属性不会返回函数,而这正是您在workOnFunctions
函数o: Record<K, Function>
中定义的。
如果您用正确的类型更改myObj
,它将起作用
// adding the type :Record<PropertyKey, Function> is optional here, and will work without having to defined the type.
myObj: Record<PropertyKey, Function> = {
a: () => 1,
b: () => "test",
c: () => 2,
d: (a : number) => a*2
}