Typescript 从具有泛型类型的对象索引调用函数
Posted
技术标签:
【中文标题】Typescript 从具有泛型类型的对象索引调用函数【英文标题】:Typescript invoke function from object index with generic type 【发布时间】:2019-08-23 01:30:11 【问题描述】:我正在尝试在 Typescript 中使用泛型,将泛型参数用作索引来调用存储在对象中的函数。 我收到的错误是:
[ts] 无法调用类型缺少调用签名的表达式。输入 '((变量: insertId: number; ) => string) | ((变量: updateId:数字;值:字符串;)=>字符串)| ((variable: deleteId: number; ) => string)' 没有兼容的调用签名。 [2349]
或
'QueryInput[T]' 类型的参数不能分配给' insertId: number; 类型的参数。 & updateId: number;值:字符串; & deleteId: number; '。 键入' insertId:数字; | updateId:数字;值:字符串; | deleteId:数字; ' 不可分配给类型 ' insertId: number; & updateId: number;值:字符串; & deleteId: number; '。 键入' insertId:数字; ' 不可分配给类型 ' insertId: number; & updateId: number;值:字符串; & deleteId: number; '。 键入' insertId:数字; ' 缺少来自类型 ' updateId: number; 的以下属性值:字符串; ':updateId,值 类型 'QueryInput[T]' 不可分配给类型 ' insertId: number; '。 键入' insertId:数字; | updateId:数字;值:字符串; | deleteId:数字; ' 不可分配给类型 ' 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]
返回的那个)。
看来query
和variables
已正确解析,并且具有适当的类型。
【问题讨论】:
它无法推断variables
的类型,因为query
的值只有在运行时才知道。因此 TypeScript 无法推断出 queries[query]
是什么,因此它假定它是所有可能的类型,但随后您声明 variables
只能是其中一种类型,它不知道是哪一种。
就像我写的那样,查询和变量都正确解析了。
【参考方案1】:
如果您想要一个快速的肮脏解决方案来使其编译,
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 的使用仍将根据您的需要在此解决方案中输入,只是它的实现不会。
直到你找到更好的解决方案..
【讨论】:
它也不起作用。它会在运行时引发相同的错误。 谢谢!我不得不升级打字稿(我有 3.2.4、3.4.1 的工作),你的解决方案成功了。以上是关于Typescript 从具有泛型类型的对象索引调用函数的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript,啥是对象文字的调用签名以及它们如何与泛型类型一起使用?
Typescript - 确保泛型属性存在于具有描述性错误的泛型类型上
在 TypeScript 中,如何在具有多个类型参数的方法中推断出泛型类型参数?
Object.keys 迭代导致 Typescript 错误“元素隐式具有‘任何’类型,因为索引表达式不是‘数字’类型”