打字稿从具有泛型类型的对象索引调用函数



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

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

类型为"QueryInput[T]"的参数不可分配给类型为"{ insertId: number; } & { updateId: number; value: string; } & { deleteId: number; }' 的参数。 键入 '{ insertId: number; } |{ updateId: number; value: string; }|{ deleteId: number; }'不可分配给类型"{ insertId: number; } & { updateId: number; value: string; } & { deleteId: number; }"。 键入"{ insertId: number; }" 不能分配给类型 '{ insertId: number; } & { updateId: number; value: string; } & { deleteId: number; }'。 类型 '{ insertId: number; }' 缺少类型 '{ updateId: number; value: string; }': updateId, value 类型"QueryInput[T]"不能分配给类型"{ insertId: number; }"。 键入 '{ insertId: number; } |{ updateId: number; value: string; }|{ deleteId: number; }'不能分配给类型"{ insertId: number; }"。 属性 'insertId' 在类型"{ updateId: number; value: string; }" 中缺失,但在类型"{ insertId: number; }" 中是必需的。TS(2345) App.tsx(7, 13): 此处声明了 'insertId'。 (参数)变量:查询输入[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已正确解析,并且具有适当的类型。

如果你想要一个快速的脏解决方案来编译它,

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 的使用仍将按照您想要的方式使用此解决方案进行键入,只是它的实现不是。

直到你找到更好的解决方案..

最新更新