TypeScript 中具有泛型类型参数的泛型类型的替代方案

时间:2021-03-13 17:04:47

标签: typescript generics typescript-generics

假设我有两种泛型函数类型,它们仅在返回类型上有所不同。一个返回类型为 T,另一个为 T[]:

type F1 = <T>(t: T) => T
type F2 = <T>(t: T) => T[]

我想知道如何将这两种类型合并为一种通用类型。我想象这样做的方法是让新的泛型类型接受另一个泛型类型作为参数(如 C++ 的 template template parameters):

// Caution, Fantasy-TypeScript ahead!

// Accepts generic type R as parameter
// to transform return type of generic function
type F<R> = <T>(t: T) => R<T>

// define F1 and F2 in terms of F
type Id<T> = T
type F1 = F<Id>
type F2 = F<Array>

但是,尚不支持通用通用参数(2021 年 3 月)。有关详细信息,请参阅 TypeScript Issuerelated SO question

TypeScript 的替代方案是什么?

1 个答案:

答案 0 :(得分:3)

一个简单的方法是使用 Conditional Types

type F<R> = <T>(t: T) => R extends void[] ? T[] : T

type F1 = F<void>   // <T>(t: T) => T
type F2 = F<void[]> // <T>(t: T) => T[]

使用 Indexed Access Types 可以实现更灵活的实现:

type R<T> = { Id: T, Array: T[] }
type F<K extends keyof R<any>> = <T>(t: T) => R<T>[K]

type F1 = F<'Id'>    // <T>(t: T) => T
type F2 = F<'Array'> // <T>(t: T) => T[]

请参阅 my answer to a similar question 以了解有关此技术的更复杂示例。