type IsSubtype<T, U> =
// 条件类型,判断T是否是U的子类型
[T] extends [U]? true : false;
type TransformType<T, U> =
// 根据T是否是U的子类型来决定转换方式
IsSubtype<T, U> extends true
// 如果是子类型,将T的所有属性值变为字符串
? {
[K in keyof T]: string;
}
// 如果不是子类型,将T的所有属性值变为数字
: {
[K in keyof T]: number;
};
每一步类型推断的实现阐述:
IsSubtype<T, U>
:
- 使用条件类型
[T] extends [U]? true : false
。这里将T
和U
分别放在数组中,是因为TypeScript在进行条件类型判断时,对于裸类型的判断可能会受到分布式条件类型的影响,而放在数组中可以避免这种情况。当T
是U
的子类型时,[T] extends [U]
条件成立,返回true
,否则返回false
。
TransformType<T, U>
:
- 外层的条件类型
IsSubtype<T, U> extends true? {... } : {... }
,根据IsSubtype
的结果进行不同的类型转换。
- 如果
IsSubtype<T, U>
为true
,即T
是U
的子类型,使用映射类型{ [K in keyof T]: string; }
。这里keyof T
获取T
类型的所有键,然后通过遍历这些键,将每个键对应的属性值类型都设置为string
。
- 如果
IsSubtype<T, U>
为false
,即T
不是U
的子类型,使用映射类型{ [K in keyof T]: number; }
。同样通过遍历T
的所有键,将每个键对应的属性值类型都设置为number
。