TypeScript 如何实现属性的类型取决于另外一个属性的值?

2022-01-21 20:22:24 +08:00
 iPhone12

代码如下,想要实现 Message 中:playload 的类型取决于 type 的值

下面已有的写法是不行的。


interface PayloadMap {
  join: PeerInfo;
  offer: RTCSessionDescriptionInit;
  answer: RTCSessionDescriptionInit;
  icecandidate: RTCIceCandidateInit;
  leave: PeerInfo;
}

// 客户端发送,服务端接受的数据格式
interface Message {
  type: 'join' | 'offer' | 'answer' | 'icecandidate' | 'leave';
  nick: string;
  id: string;
  
  // playload 的类型取决于 type 的值
  payload: PayloadMap[Message['type']];
}

比如:

const m: Message = {
  type: 'join',
  nick: 'Fuck',
  id: '123456',
  payload: {
    // 此时 payload 应该是 PeerInfo 类型
  }
}
1735 次点击
所在节点    TypeScript
3 条回复
rabbbit
2022-01-21 20:57:04 +08:00
interface Foo {

}

interface Bar {

}

interface PayloadMap {
  join: Foo;
  offer: Bar;
}

type Message = { [k in keyof PayloadMap]: {
  type: k;
  payload: PayloadMap[k];
} }[keyof PayloadMap];

const m: Message = {
  type: 'join',
  payload: {
 }
}

const n: Message = {
  type: 'offer',
  payload: {
 }
}
iPhone12
2022-01-21 21:15:21 +08:00
@rabbbit 学到了,感谢!

map 出一个 key 对应一个类型,然后联合。妙!
fifa666
2022-04-14 11:01:49 +08:00
interface PayloadMap {
join: 'join';
offer: RTCSessionDescriptionInit;
answer: RTCSessionDescriptionInit;
icecandidate: RTCIceCandidateInit;
leave: 'leave';
}

interface Message<T, P extends keyof T> {
type: P;
nick: string;
id: string;
payload: T[P];
}


const m: Message<PayloadMap, 'join'> = {
type: 'join',
nick: 'Fuck',
id: '123456',
payload: "join"
};

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/829803

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX