TypeScript:将数组传递给变量而不是直接传递给函数时出错 [英] TypeScript: Error when passing an array in a variable rather than direcly to a function
问题描述
以下函数 workOnFunctions
接受一个对象和该对象的键数组,其中所有键都映射到一个函数:
const myObj = {a: () =>1、b: "测试",c: 2,d:(a:数字)=>a2}function workOnFunctions (o: Record, names: K[]) {names.forEach(name => {const f = o[名称];//用函数 f 做一些事情})}
我注意到当我这样做时它按预期工作:
workOnFunctions(myObj, ["a", "d"]);//有效
但是当将数组存储在变量中然后将此变量传递给函数时,我得到错误
'{ a: () => 类型的参数数字;b:字符串;c:数量;d: (a: 数字) =>数字;}' 不能分配给类型为'Record'的参数.属性b"与索引签名不兼容.类型 'string' 不能分配给类型 'Function'.
代码:
const names = ["a", "d"];workOnFunctions(myObj,名称);
为什么会这样?似乎编译器无法正确推断 names
的类型.当我直接传递数组时,它可以.我也试过这个:
const names = ["a", "d"] as const;workOnFunctions(myObj,名称);
这也不起作用.
我的最终目标是编写一个函数,该函数接受一个对象和一个指向该对象内函数的键数组.
找到部分解决方案,但我不明白为什么
看起来像这样:
type KeysMatching= { [K in keyof T]: T[K] 扩展 V ?K : 从不 }[keyof T]const 名称:Array>= ["a", "d"];workOnFunctions(myObj,名称);
我从这里得到了 KeysMatching
:TypeScript:接受映射到特定类型的所有对象键
但是为什么我直接传数组的时候编译器可以自己推断出这个复杂类型呢?使用单独的数组时是否也有自动推断类型的技巧?
你的错误不是因为 names
数组,而是因为你的 myObject
,"b" 和 "c" 属性不返回函数,这是您在 workOnFunctions
函数 o: Record
中定义的.>
如果您使用正确的类型更改您的 myObj
,它将起作用
//添加类型 :Record在这里是可选的,无需定义类型即可工作.myObj:记录= {a: () =>1、b: () =>测试",c: () =>2、d:(a:数字)=>a2}
The following function workOnFunctions
takes an object and an array of keys to that object where all the keys map to a function:
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
})
}
I noticed that it works as intended when I do this:
workOnFunctions(myObj, ["a", "d"]); // works
But when storing the array in a variable and then passing this variable to the function, I get the error
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'.
Code:
const names = ["a", "d"];
workOnFunctions(myObj, names);
Why is that the case? It seems like the compiler can't infer the type of names
correctly. When I pass the array directly, it can. I also tried this:
const names = ["a", "d"] as const;
workOnFunctions(myObj, names);
Which does not work either.
My final goal is to write a function that takes an object and an array of keys that point to functions within that object.
EDIT: Partial solution found, but I don't understand why
Looks like this works:
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);
I got KeysMatching
from here: TypeScript: Accept all Object keys that map to a specific type
But why can the compiler infer this complex type by itself when I directly pass the array? Is there a trick to auto-infer the type also when using a separate array?
Your error is not because of the names
array, but because of your myObject
,
the "b" and "c" properties does not return a function, which is what you have defined in your workOnFunctions
function o: Record<K, Function>
.
If you change your myObj
with the correct types, it will work
// 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
}
这篇关于TypeScript:将数组传递给变量而不是直接传递给函数时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!