繁体   English   中英

TypeScript:如何获取具有指定参数元组类型的泛型函数实例的返回类型?

[英]TypeScript: How to obtain return type of the instance of a generic function that has a specified parameter tuple type?

假设我有通用功能

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< >等于anyunknown ,具体取决于我列出这两种类型的顺序在路口。 另外,因为函数类型在它们的参数中是逆变的,所以我尝试采用这两种类型的联合的ReturnType< > ,但这也没有帮助。 欢迎任何建议或指导。

(我关于不知道模板结构的观点是我没有能够说ReturnType<typeof example<string>>的信息,因为可能匹配参数[string, number]的实例化实际上是example<number>因为example在第二个参数类型上实际上是通用的,并且在第一个参数中显式为字符串。用例是我得到一个对象,其值是我可能想要调用的替代函数,其中一些可能是通用的,并且我正在根据我拥有的参数元组的类型来选择要调用的那个。那部分有效——我可以成功地提取键(作为一个具体类型,只有一个字符串居民),其值为 a(可能是通用的)函数在我得到的参数的元组类型上可调用,但我还需要表达调用将产生的返回类型,我似乎无法管理它。)

更新:我正在尝试完成的精简示例是在这个操场上。 它显示了选择正确的密钥,以及一次获取“匹配实例化”的返回类型的不成功尝试。

不,不幸的是,从 TS4.9 开始,这在 TypeScript 中是不可能的。 无法在类型级别表达对泛型的操作; 正如microsoft/TypeScript#1213的长期开放功能请求中所要求的,没有“泛型泛型”或更高种类的类型。

因此,如果您实际在表达式级别调用函数(如果代码中出现example("abc", 123) ,虽然编译器可以在给定特定输入的情况下找出通用函数的输出类型,但甚至还有一些支持高阶泛型函数(例如call(example, "abc", 123)如果call的类型为<A extends any[], R>(f: (...args: A)=>R, ...args: A)=>R string <A extends any[], R>(f: (...args: A)=>R, ...args: A)=>R ), 没有纯类型级别的等价物。 在某些时候,您必须实际调用具有实际输入的函数(或说服编译器您正在这样做)以查看输出类型。

microsoft/TypeScript#17961有一个 pull request,它可以启用类型级函数应用程序,因此,有了type Example = typeof example你可以写type RetType = Example(string, number) 但这从未合并到语言中,并且基本上与microsoft/TypeScript#6606的大部分内容一起被放弃了,这是一个通用请求,即能够查询所有表达式的类型,而实际上不需要将这些表达式发送到 JavaScript。

目前在microsoft/TypeScript#40179有一个开放的功能请求用于此功能。 它被列为等待更多反馈,这意味着他们在考虑将其作为语言的一部分之前需要听取更多的社区参与。 如果它对你很重要,你可以给它一个,并描述你的用例以及它为什么引人注目。 但我没有看到任何迹象表明它会很快发生,即使它有更多的参与度。

这一切都意味着编译器不能为你做这件事,你需要要么完全放弃,要么重构你的代码,以便你手动进行类型处理(也许你可以让编译器检查你已正确完成)。 但是这样的解决方法并不令人愉快,并且不直接在这个问题的范围内。

[编辑:更正了上面的问题编号。]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM