为什么Typescript联合+映射类型在使用和不使用泛型时工作方式不同?



我是使用泛型的新手。以下代码有不同的"w0"one_answers"w1",但代码看起来是一样的。

为什么它们不同,以及如何用相反的方法得到相反的类型

我已经看了一些文档,但是我没有找到任何解释,有没有什么文档可以解释他们不同类型的原理?

如果没有CalcGenerics,我怎么得到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;
// }

游乐场

相关内容

  • 没有找到相关文章

最新更新