我是使用泛型的新手。以下代码有不同的"w0"one_answers"w1",但代码看起来是一样的。
为什么它们不同,以及如何用相反的方法得到相反的类型
我已经看了一些文档,但是我没有找到任何解释,有没有什么文档可以解释他们不同类型的原理?
如果没有Calc
和Generics
,我怎么得到Calc<BaseA> | Calc<BaseB>
如何用Generics
得到{ type: "A" | "B"; flag: number; }
type BaseA = {
type: 'A'
name: string
flag: number
}
type BaseB = {
type: 'B'
id: number
flag: number
}
type Base = BaseA | BaseB
type w0 = {
[k in keyof Base]: Base[k]
}
/*
w0 = {
type: "A" | "B";
flag: number;
}
*/
type Calc<W> = {
[k in keyof W]: W[k]
}
type w1 = Calc<Base>
/*
w1 = Calc<BaseA> | Calc<BaseB>
*/
type z0 = Exclude<w0,BaseA>
// z0 = w0
type z1 = Exclude<w1,BaseA>
// z1 = BaseB
type Q1 = {
[B in Base as B["type"]]: {
[K2 in keyof B]: B[K2]
}
}[Base["type"]]
// type Q1 = {
// type: 'A';
// name: string;
// flag: number;
// } | {
// type: 'B';
// id: number;
// flag: number;
// }
首先映射Base
中的每个元素,并将type
键作为结果类型的键。对于每个元素,我们可以映射元素的键。最后,用Base["type"]
索引该类型以获得联合。
您现在可以用Calc
替换内部映射。
type Q1 = {
[B in Base as B["type"]]: Calc<B>
}[Base["type"]]
// type Q1 = Calc<BaseA> | Calc<BaseB>
第二个问题有点棘手。它是由分配条件类型引起的。我发现只能使用以下技巧禁用分发性:
type Calc2<W extends [any]> = {
[k in keyof W[0]]: W[0][k]
}
type Q2 = Calc2<[Base]>
// type Q2 = {
// type: "A" | "B";
// flag: number;
// }
游乐场