Typescript从具有普通类型

时间:2019-04-01 19:56:17

标签: typescript generics web

我正在尝试在Typescript中使用泛型,以便将泛型参数用作索引来调用存储在对象中的函数。
我收到的错误是:

  

[ts]无法调用类型缺少调用签名的表达式。类型'((变量:{insertId:number;})=>字符串)| ((变量:{updateId:数字;值:字符串;})=>字符串)| ((variable:{deleteId:number;})=>字符串)'没有兼容的呼叫签名。 [2349]

  

“ QueryInput [T]”类型的参数不能分配给“ {{insertId:number; }&{updateId:number;值:字符串; }&{deleteId:number; }'。     输入'{insertId:number; } | {updateId:number;值:字符串; } | {deleteId:number; }'不可分配给类型'{insertId:number; }&{updateId:number;值:字符串; }&{deleteId:number; }'。       输入'{insertId:number; }'不可分配给类型'{insertId:number; }&{updateId:number;值:字符串; }&{deleteId:number; }'。         输入'{insertId:number; }”缺少类型“ {updateId:number;值:字符串; }':updateId,值           类型'QueryInput [T]'不能分配给类型'{insertId:number; }'。             输入'{insertId:number; } | {updateId:number;值:字符串; } | {deleteId:number; }'不可分配给类型'{insertId:number; }'。               类型'{updateId:number;缺少属性'insertId'。值:字符串; }”,但类型为“ {insertId:number; }'。ts(2345)   App.tsx(7,13):在此声明“ insertId”。   (参数)变量:QueryInput [T]

下面是一个复制该问题的示例代码:

type Query = "insert" | "update" | "delete";

interface QueryInput {
  insert: { insertId: number };
  update: { updateId: number; value: string };
  delete: { deleteId: number };
}

type QueryObject = { [T in Query]: (variable: QueryInput[T]) => string };

const queries: QueryObject = {
  insert: variable => "insert",
  update: ({ updateId, value }) => "update",
  delete: variable => "delete"
};

const getQuery = <T extends Query>(query: T, variables: QueryInput[T]) => {
  return queries[query](variables); // this line throws an error
}

Typescript引擎似乎无法解析函数的正确签名-尽管肯定只有1种可能的签名(从queries[query]返回的签名)。
似乎queryvariables已正确解析,并具有适当的类型。

1 个答案:

答案 0 :(得分:0)

如果您想使用快速的肮脏解决方案进行编译,

const getQuery = <T extends Query>(query: T, variables: QueryInput[T]) => {
  let v: any = variables;
  return queries[query](v); // this line doesnt throw an error
}

这不是理想的选择,但是getQuery本身似乎并不需要进行任何更改。 而且,对于此解决方案,仍然可以按您的要求键入getQuery的用法,而无需输入实现。

直到您找到更好的解决方案。