TypeScript 泛型怎么只给后面的类型设置类型

例如我有下面这个类型定义:

interface Touch<
    Detail extends IAnyObject = IAnyObject,
    T extends TouchDetail | TouchCanvasDetail = TouchDetail,
    TargetDataset extends IAnyObject = CurrentTargetDataset
> {
    detail: Detail
    touches: T[]
    dataset: TargetDataset
}

因为所有的泛型定义都有默认值,所以我只希望设置后面的像 TargetDataset 应该怎么设置呢?

为了便于理解,下面是我写的伪代码,当然它不能正常工作:

const touch: Touch< , , { id: number }> = ...
###

这个问题六年前就有人提议过了:https://github.com/Microsoft/...

感兴趣可以进去看看社区里的讨论,里面就提到过你这种空逗号的写法。还有一种是用 * 的(Flow.js 里支持的是这种):

const touch: Touch<*, *, { id: number }>

不过遗憾的是到今天为止 TS 还不支持此特性,所以现阶段的话你还是得手动写上:

const touch: Touch<IAnyObject, TouchDetail, { id: number }>
###

这个并不难吧。

type ExtractGenericType1<T> = T extends Touch<infer V> ? V : never;
type ExtractGenericType2<T> = T extends Touch<any, infer V> ? V : never;

type GenericType1 = ExtractGenericType1<Touch>;
type GenericType2 = ExtractGenericType2<Touch>;

type OptionalTypedTouch<T> = Touch<GenericType1, GenericType2, T>;

let touch: OptionalTypedTouch<{ id: number }>;

如果非要按照可选参数的格式,可以自定义个占位符

enum _ {}

type OptionalGenericTypedTouch<
    Detail extends (IAnyObject | _) = IAnyObject,
    T extends (TouchDetail | TouchCanvasDetail | _) = TouchDetail,
    TargetDataset extends (IAnyObject | _) = CurrentTargetDataset
> = Touch<
    Detail extends _ ? (Touch extends Touch<infer V> ? V : never) : Detail,
    T extends _ ? (Touch extends Touch<any, infer V> ? V : never) : T,
    TargetDataset extends _ ? (Touch extends Touch<any, any, infer V> ? V : never) : TargetDataset
>;

let touch: OptionalGenericTypedTouch<_, _, { id: number }>;
转自:https://www.dianjilingqu.com/
posted @ 2022-05-14 13:04  元宇宙-Metaverse  阅读(73)  评论(0)    收藏  举报