假设我有泛型函数
function example<T>(a: T, b: number): SomeType<T> {
// code goes here
}
但是为了方便讨论,我不知道example
是第一个还是第二个参数的泛型,也可能是带有两个类型参数的泛型。我的目标是确定接受参数元组[string, number]
的example
示例化的返回类型。(所以如果有InstantiatedReturnType<F, ParamTuple>
这样的东西就好了,这样在本例中InstantiatedReturnType<typeof example, [string, number]>
就变成了SomeType<string>
。)我已经验证了typeof example
确实扩展了(...args: [string, number]) => any
类型,但是我还没有找到一种方法来提取具有这种参数元组类型的示例化的返回类型。如果我取函数类型typeof Example
和(...args: [string, number]) => any
的交集,则ReturnType< >
等于any
或unknown
,这取决于我在另外,因为函数类型在它们的参数中是逆变的,所以我尝试取这两个类型的并集的ReturnType< >
,但是也没有帮助。欢迎任何建议或指导。
(My关于不知道模板结构的一点是我没有能够说ReturnType<typeof example<string>>
的信息,因为匹配参数[string, number]
的示例化可能实际上是example<number>
,因为example
实际上是第二个参数类型的泛型,并且在第一个参数中显式地作为字符串。用例是给我一个对象,它的值是我可能想要调用的替代函数,其中一些可能是泛型的,并且我根据参数元组的类型匹配来选择要调用的那个。这部分工作正常--我可以成功地提取密钥(作为只有一个字符串居民的具体类型),其值为(可能是泛型的)函数,可以在我得到的参数的元组类型上调用,但是我还需要表达调用将产生的返回类型,而我似乎无法处理这一点。)
UPDATE:在这个操场上有一个我试图完成的精简示例。它显示了选择正确的键,以及一次获取“匹配示例化”的返回类型的失败尝试。
1条答案
按热度按时间g2ieeal71#
不,遗憾的是,这在TS4.9的TypeScript中是不可能的。没有办法在类型级别表达泛型上的操作;不存在如在microsoft/TypeScript#1213处的长期开放特征请求中所请求的“generic泛型”或 * 更高种类的类型 *。
因此,虽然编译器可以在给定特定输入 * 的情况下计算出泛型函数的输出类型,但如果您实际上在表达式级别调用函数(如果代码中出现
example("abc", 123)
),而且甚至还支持更高阶的泛型函数(例如,如果call
具有类型<A extends any[], R>(f: (...args: A)=>R, ...args: A)=>R
,则可以使call(example, "abc", 123)
产生string
),没有纯粹的类型级等价物。在某些情况下,你必须用实际的输入来调用函数(或者让编译器相信您正在这样做)来查看输出类型。在microsoft/TypeScript#17961上有一个pull请求,它可以启用类型级函数应用程序,因此,使用
type Example = typeof example
,您可以编写type RetType = Example(string, number)
。但这从未被合并到语言中,并且基本上与microsoft/TypeScript#6606的大部分内容沿着被放弃。microsoft/TypeScript#6606是一个通用请求,能够查询所有表达式的类型,而实际上不需要将这些表达式发送到JavaScript。目前microsoft/TypeScript#40179上有一个开放的功能请求。它被列为等待更多反馈,这意味着他们需要听取更多的社区参与之前,甚至考虑使它成为语言的一部分。如果它对你很重要,你可以给予它一👍个,并描述你的用例和为什么它是引人注目的。但我没有看到任何迹象表明它会很快发生。即使它有更多的参与。
这意味着编译器不能为你做这些,你要么完全给予,要么重构你的代码,这样你就可以手动地做类型处理(也许你可以让编译器检查你做得是否正确),但是这样的变通方法并不令人愉快,也不在这个问题的范围之内。
[Edit:更正上述问题编号。]