首页 > 解决方案 > 使用嵌套的泛型参数定义类型别名

问题描述

我希望能够定义一个接受泛型参数的类型(它本身扩展了具有 2 个泛型参数的类型)并使用嵌套的泛型参数定义其约束。

// Boiler plate for example setup:
type NodeCallback<T> = (err?: Error | void, result?: T) => void
type Handler<I, R> = (event: I, callback: NodeCallback<R>) => void
type StrToNumHandler = Handler<string, number>

// I end up having to do this:
type WorkaroundAsyncHandler<T extends Handler<I, R>, I, R> = (event: I) => Promise<R>
type WorkaroundStrToNumHandler = WorkaroundAsyncHandler<StrToNumHandler, string, number>

// I'd like to be able to just write this:
type AsyncHandler<T extends Handler<I, R>> = (event: I) => Promise<R> // This is a compiler error. Not sure how to write this in a valid way.
type AsyncStrToNumHandler = AsyncHandler<StrToNumHandler> // This is the line I'd ultimately like to write

我有编译的解决方法,但是如果我提供 and 的值IR那么提供 没有任何价值Handler,我希望能够做到这一点。

标签: typescripttypes

解决方案


您可以非常接近条件类型和条件类型中的类型推断

type AsyncHandler<T> = T extends Handler<infer I, infer R> ? 
                             (event: I) => Promise<R> 
                          :  never
;

type AsyncStrToNumHandler = AsyncHandler<StrToNumHandler> 
// inferred as AsyncStrToNumHandler = (event: string) => Promise<number>

缺点是您的类型别名应该提供某种类型,即使T实际上不是Handler。通常的解决方案是返回never类型。但是使用这种别名的代码在接收never类型时可能会在编译时出现意外行为。


推荐阅读