typescript - 如何在接口中返回一个方法的 ReturnType 元组,它是一种可变参数
问题描述
我想写完一个如下所示的方法。该接口A
是生成器的配置类型,我将对不同类型的生成器进行不同的配置,并在函数f
中一次使用它们,以便在一个元组中获取所有生成的值。
interface A<Output> {
f: () => Output;
};
const a: A<string> = {
f: () => 'Hello',
};
const b: A<number> = {
f: () => 42,
};
function f(...x: ???): ??? {
return x.map(x => x.f());
}
const y: [string, number] = f(a, b);
console.log(y) // ['Hello', 42]
我怎样才能做到这一点而不会出现任何错误?
解决方案
您可以将函数表示为作用于泛型映射元组的类型。如果输出是 type 的元组T
,那么输入是 type ,意思是:对于元组中的{[I in keyof T]: A<T[I]>}
每个索引,输入应该是 type ,输出应该是 type :I
T
A<T[I]>
T[I]
function f<T extends any[]>(...x: { [I in keyof T]: A<T[I]> }) {
return x.map(x => x.f()) as T;
}
请注意,编译器不会也可能永远无法验证x.map(...)
实际产生了预期类型的值;即使通常表示这样的转换也需要TypeScript 目前不支持的更高种类的类型(有关相关功能请求,请参见microsoft/TypeScript#1213 )。最简单的事情就是我在上面所做的:只需断言输出将是 type T
,通过编写x.map(...) as T
.
让我们确保它有效:
const y = f(a, b); // [string, number]
console.log(y[0].toUpperCase()) // "HELLO"
console.log(y[1].toFixed(2)) // "42.00"
是的,看起来不错。
哦,您可以使用ReturnType<T>
实用程序类型将此转换表示为某种东西,但编写起来更麻烦:
function f<T extends A<any>[]>(...x: T) {
return x.map(x => x.f()) as {
[I in keyof T]: ReturnType<Extract<T[I], A<any>>["f"]>
};
}
不过,它在调用者方面的行为类似。
推荐阅读
- asp.net - ASP.NET 核心 JWT 身份验证总是抛出 401 未授权
- spring-boot - 用于从控制器重定向的 Hystrix 后备方法
- java - ListView 或 false 方法获取结果
- bash - $$ 在 shell , Linux
- html - 如何保留现有的 SVG 形状而不是替换它们?
- html - 如何将 WebRTC 连接到 SFU 中的 NodeJS 服务器?
- kotlin - 如何在 Kotlin 中为 Autoboxing 生成警告?
- ios - 以编程方式自定义标签栏
- java - 如何在 Android Studio 中决定什么应该是静态的
- java - 在 Eclipse 中编辑 Play 2.8 Twirl 模板