我正在尝试在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]
返回的签名)。
似乎query
和variables
已正确解析,并具有适当的类型。
答案 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的用法,而无需输入实现。
直到您找到更好的解决方案。