typescript - 接口(interface)与类型字段的联合,创建一个类型为 : type - specific attribute of that types interface 的对象

标签 typescript union-types

这个问题很难用语言解释,但用代码很容易解释:-)这就是我想要实现的目标( TS Playground )

enum ActionType {
  Add =  'add',
  Concat = 'concat'
};

interface AddActionPayload {
  num1: number;
  num2: number;
}

interface ConcatActionPayload {
  str1: string;
  str2: string;
}

interface AddAction {
    type: ActionType.Add;
    payload: AddActionPayload;
}

interface ConcatAction {
    type: ActionType.Concat;
    payload: ConcatActionPayload;
}

type Actions = AddAction | ConcatAction;

const payloads: Record<ActionType, Actions['payload']> = {
  add: {
    // accept only AddActionPayload
  },
  concat: {
    // accept only ConcatActionPayload
  }
}

知道如何实现这一目标吗?

最佳答案

Record<K, V> utility typemapped type其中键和值类型完全不相关。其形式为type Record<K, V> = {[P in K]: V} ,其中每个键的键类型 P (迭代 K 成员的 union )对相应的值类型没有任何影响,即 V无论。所以你会得到你不喜欢的行为:

type Oops = Record<ActionType, Actions['payload']>;
/* type Oops = {
    add: AddActionPayload | ConcatActionPayload;
    concat: AddActionPayload | ConcatActionPayload;
} */

相反,您应该编写一个映射类型,其中值显式依赖于键。因为你有一个 Actions union代表你想要的信息,最简单的就是直接映射到Actions使用key remapping在映射类型中提取键类型和值类型。

看起来像这样:

type Payloads = { [T in Actions as T['type']]: T['payload'] };
/* type Payloads = {
    add: AddActionPayload;
    concat: ConcatActionPayload;
} */

这就是你想要的行为:

const payloads: Payloads = {
  add: { num1: 1, num2: 2 },
  concat: { str1: "a", str2: "b" }
}; // okay

const badPayloads: Payloads = {
  add: { str1: "a", str2: "b" },
  concat: { num1: 1, nume2: 2 }
};  // error!

Playground link to code

关于typescript - 接口(interface)与类型字段的联合,创建一个类型为 : type - specific attribute of that types interface 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74321882/

相关文章:

javascript - 正则表达式 : Get value of last bracket from the string

javascript - const 声明需要一个初始化值

html - NgFor 没有显示我给他的数组

javascript - 有没有办法在联合类型上调用数组原型(prototype)方法?

javascript - 如何将 JS 字符串数组转换为与 io-ts 的联合?

typescript - 尝试访问 AVPlaybackStatus 的错误属性时出错

typescript - 类型错误 : Cannot read property 'next' of null in Angular2 Observable

typescript - 与字符串一起使用时,TypeScript 管道运算符是什么意思?

arrays - TypeScript:来自字符串联合文字数组类型,不允许数组中存在任何冗余值

reactjs - React.FunctionComponent 和 React.SFC 的区别