【发布时间】: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只能是其中一种类型,它不知道是哪一种。 -
就像我写的那样,查询和变量都正确解析了。
标签: typescript generics web