【问题标题】:TypeScript: Error when passing an array in a variable rather than direcly to a functionTypeScript:将数组传递给变量而不是直接传递给函数时出错
【发布时间】: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);

我从这里得到KeysMatchingTypeScript: Accept all Object keys that map to a specific type

但是为什么我直接传递数组时编译器可以自己推断出这种复杂类型呢?使用单独的数组时是否也有自动推断类型的技巧?

【问题讨论】:

    标签: typescript types


    【解决方案1】:

    你的错误不是因为names数组,而是因为你的myObject, "b" 和 "c" 属性不返回函数,这是您在 workOnFunctions 函数 o: Record&lt;K, Function&gt; 中定义的。

    如果您将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
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-28
      • 2016-03-03
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多