TypeScript:将数组传递给变量而不是直接传递给函数时出错 [英] TypeScript: Error when passing an array in a variable rather than direcly to a function

查看:29
本文介绍了TypeScript:将数组传递给变量而不是直接传递给函数时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下函数 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆