【问题标题】:Create Record-like type from union type从联合类型创建类记录类型
【发布时间】:2020-05-01 17:52:43
【问题描述】:

在 Typescript 中,我创建了一个具有共享“类型”属性的联合类型:

export type Instruction =
  | { type: 'local.set', name: string, value: Expression }
  | { type: 'i32.const', value: number }
  | { type: 'i32.add', left: Expression, right: Expression };

我想创建一个对象,其“类型”属性的值作为键,值作为函数。像这样:

const visitor: Record<Instruction['type'], (instruction: Instruction) => void> = {
   'local.set': (instruction) => {},
   'i32.const': (instruction) => {},
   'i32.add': (instruction) => {},
}

但是“指令”参数的输入对我来说太笼统了。我想知道我可以从函数内访问指令中的哪些属性。 那么如何使用Instruction 类型中的'type' 属性的所有键以及它们各自的Instruction 类型作为值来创建Record 类似类型?

换句话说;如果我这样做,Typescript 可以推断出类型:

const instruction: Instruction = { type: 'local.set' }; // TS knows about the missing 'name' and 'value' properties

但我想做这样的事情:

const instruction: Instruction[where type = 'local.set'] = { type: 'local.set' };

这可能吗,怎么做?

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    您可以使用自定义映射类型来映射type 的并集,然后使用Extract 条件类型从Instruction 中获取与当前属性具有相同类型的并集成分:

    export type Instruction =
        | { type: 'local.set', name: string, value: Expression }
        | { type: 'i32.const', value: number }
        | { type: 'i32.add', left: Expression, right: Expression };
    
    type Visitor<T extends { type: string}> = {
        [P in T['type']]: (instruction: Extract<T, { type: P }>) => void
    }
    const visitor: Visitor<Instruction> = {
        'local.set': (instruction) => { instruction.name},
        'i32.const': (instruction) => { instruction.value },
        'i32.add': (instruction) => {  instruction.right },
    }
    

    Playground Link

    【讨论】:

      猜你喜欢
      • 2020-02-08
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 2021-12-02
      • 2018-09-06
      • 1970-01-01
      相关资源
      最近更新 更多