关于"in"操作符在typescript类型中作用,这段官方的代码有点看不懂,求解释?

新手上路,请多包涵
type EventConfig<Events extends { kind: string }> = {
    [E in Events as E["kind"]]: (event: E) => void;
}

type SquareEvent = { kind: "square", x: number, y: number };
type CircleEvent = { kind: "circle", radius: number };
 
type Config = EventConfig<SquareEvent | CircleEvent>

//type Config = {
    square: (event: SquareEvent) => void;
    circle: (event: CircleEvent) => void;
}

[E in Events as E["kind"]]这段代码不太理解,如果写成 E in keyof Events能理解成E是Events对象的每一个key,但是直接E in Events那这个E代表什么呢?

阅读 381
avatarAI BotBETA

在 TypeScript 中,in 关键字在类型系统中用于映射类型(Mapped Types)。当你看到 [E in Events as E["kind"]]: (event: E) => void; 这段代码时,它实际上是在创建一个新的类型,该类型的属性键由 Events 类型的 kind 属性值确定,并且每个属性的值是一个函数,该函数接受一个与相应 kind 值相对应的事件类型作为参数。

在这个例子中,Events 是一个泛型参数,代表一个对象类型,该对象有一个 kind 属性。Events 可以是任何具有 kind 属性的对象类型。

[E in Events as E["kind"]]: (event: E) => void; 这段代码的解释如下:

  • E in Events:这里的 EEvents 类型中每个属性的名称。但是,由于我们使用了 as E["kind"],这实际上会将 E 解释为 Events 中每个属性的 kind 值。
  • as E["kind"]:这会将键名(即 E)映射为 Events 中相应属性的 kind 值。在这个例子中,Events 可以是 SquareEventCircleEvent,因此 E["kind"] 的值将是 "square""circle"
  • (event: E) => void:对于每个 kind 值,我们定义一个函数类型,该函数接受一个参数 event,其类型为与 kind 值相对应的 Events 类型。

因此,当你使用 EventConfig<SquareEvent | CircleEvent>,你会得到以下类型:

{
    square: (event: SquareEvent) => void;
    circle: (event: CircleEvent) => void;
}

这里,EE in Events 中实际上是一个类型变量,代表 Events 中每个属性的类型。然后,通过 as E["kind"],我们将这些属性名映射为它们相应的 kind 值,从而得到一个新的类型,其属性名由 Events 中每个属性的 kind 值确定。

1 个回答

in 可以遍历联合类型中的每一个类型

type In<T extends string | number | symbol> = {
    [K in T]: K
}

type TypeA = 1
type TypeB = "2"
type TypeC = "c"

type A = In<TypeA | TypeB | TypeC>

==>

type A = {
    1: 1;
    2: "2";
    c: "c";
}

K 依次为 TypeATypeBTypeC

logo
Microsoft
子站问答
访问
宣传栏