【发布时间】:2022-11-16 15:19:34
【问题描述】:
我在库中有一个类型,我想通过更改该类型中每个函数签名的返回类型来修改它。
interface Chainer<Subject> {
(chainer: 'be.a', type: string): Cypress.Chainable<Subject>
(chainer: 'be.above', value: number | Date): Cypress.Chainable<Subject>
// ... many many more overloads here
}
我想创建一个 util 类型,它可以将所有函数签名转换为具有不同的返回类型。
// This is the util that should change the return type
type RemapFunctionReturnType<T, U> = T extends (...args: infer P) => any ? (...args: P) => U : never;
type ModifiedChainer = RemapFunctionReturnType<Chainer<any>, number>;
// All return types changed to number
// interface ModifiedChainer<Subject> {
// (chainer: 'be.a', type: string): number;
// (chainer: 'be.above', value: number | Date): number;
// // ... many many more overloads here
// }
需要帮助使所有签名的重映射函数返回类型递归。到目前为止,这是我尝试过的方法,但它仅适用于单个签名:
type RemapFunctionReturnType<T, U> = T extends (...args: infer P) => any & infer Next ? (...args: P) => U | RemapFunctionReturnType<Next, U> : never;
【问题讨论】:
-
这是 TypeScript 的设计限制或缺失功能,请参阅ms/TS#29732。不能(轻易地)在类型系统中以编程方式操作重载;一般来说,您只会得到最后一个签名。这里的任何解决方法都必然只适用于一些任意选择的有限数量的重载,并且将涉及编写大小随该数量缩放的实用程序类型。不幸的是,如果您正在为单个类型执行此操作,您应该只复制类型定义并对其进行查找替换。
-
这是否完全解决了您的问题?如果是这样,我可以写一个答案来解释(假设我没有找到重复的)。如果没有,我错过了什么? (如果您回复,请提及@jcalz 以通知我。)
-
我看这很不幸。我一直在复制和修改这些类型,但一直在寻找一种不必重复工作的方法。
标签: typescript