enum Type {
Title = 'Title',
Input = 'Input',
}
type InputConfType = number;
type TitleConfType = string
// map 1 对 1
type ConfList = {
[Type.Input]: InputConfType,
[Type.Title]: TitleConfType,
};
// 想生成一个接口 A, 确保 type 和 conf 获得对应类型, 适用于以下情况
const Input : A ={
type: Type.Input,
conf: 11
}
const Title : A ={
type: Type.Title,
conf: 'str'
}
// 如果出现有以下情况则报错
const ErrorTemplate : A ={
type: Type.Input,
conf: 'str
}
想象中的 A 接口 效果 类似于, 求解....
interface A < T=ConfList, K=keyof T > {
type: K;
conf: T[K]
}
Ts 想写完美, 特别是涉及 约束 真像是戴着镣铐跳舞....
as
一把梭又感觉不太优雅~~~
🐶
1
Opportunity 2023-10-13 21:19:29 +08:00 1
|
2
lqzhgood OP @Opportunity #1
大佬 NB, 完全没想到可以用辅助类型 我继续简化了一下 ```ts // # 1 interface _A<T extends Type> { type: T; conf: ConfList[T]; } // # 2 type A <U = Type> = (U extends Type ? _A<U> : never) ``` 但是还有个疑问 #1 的作用 根据传入的泛型返回约束的类型, 返回结果等于 { type: Type.Input, conf: InputConfType } | { type: Type.Title, conf: TitleConfType} #2 如果我写成 type A = _A<Type> 为啥就不行呢 ? 这不是和 #2 等价么... |
3
YuJianrong 2023-10-14 03:22:02 +08:00 1
这是 Conditional Types( 就是这个:x extends TypeA ? A : B )的特性。
做 Conditional Types 的时候,Typescript 编译器会把 union 分开一个个 map 去算,然后再合成一个 union 。所以 A<Type> 相当于 A<Type.Title | Type.Input> 相当于 (Type.Title extends Type ? _A<Type.Title> : never) | ( Type.Input extends Type ? _A<Type.Input> : never) 你直接 _A<Type> 当然就没有这个效果了。 文档: https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types |
4
lqzhgood OP @YuJianrong 受教了 谢谢~
|