网站搜索

泛型 - 我可以定义一个 TypeScript 映射,使每个值的约束对应其键吗?


在这个游乐场中,我想创建一个地图,其中每种类型的 Action 联合类型最多只包含一个动作。每个联合类型通过具有不同的字符串字面量属性 ‘type’ 来区分。我有这个地图的定义,它可以编译,但太宽松了……

const lastAction:{
    [A in Action["type"]]?:Action 
} = {}

lastAction 映射中键的约束规定...

  • key 是某种 Action 类型的 “type” 属性
  • 该值必须是某种 Action 类型

...它当前并不强制要求键和值来自 相同 的 Action 类型。理想情况下,当 playground 的最后一行尝试将类型为 “snooze” 的 Action 分配给名为 “fulfil” 的属性时,应该会作为编译器错误失败。

lastAction["fulfil"]=snoozeAction

我只是忽略了显而易见的东西。我确信有某种方法可以使用分配条件或更简单的方式来实现。下面的伪代码是垃圾的 TypeScript,因为泛型不能像这样按属性使用,但它给出了我想要的思路……

const lastAction: {
    [key:A["type"]]:A extends Action
} = {};

答案#1

使用 TypeScript 4.1 的键重映射,这非常容易:

const lastAction:{
    [A in Action as A["type"]]?: A 
} = {}