Typescript 根据一个成员变动推断另一个成员的类型

2021-07-26 15:18:25 +08:00
 WynneChan

各位大佬,假设有这样一个 IMessage 的 interface,然后需要通过 type 的值来推断 value 的值。有这种可能性吗

enum MessageEnum{ IMAGE:'image', Text:'text' }

interface IMessage{ type:MessageEnum, value:IMessageContentMap[这里是 type 的值] }

interface IMessageContentMap{ [MessageEnum.IMAGE]:string; [MessageEnum.Text]:number; }

1123 次点击
所在节点    TypeScript
6 条回复
noe132
2021-07-26 15:57:52 +08:00
interface A { type: 'A', data: number }
interface B { type: 'B', data: string }

if (a.type === 'B') {
a.data // number
}

以你的例子

enum MessageEnum { IMAGE = 'image', Text = 'text' }

interface IMessage <T extends MessageEnum>{
type: T,
value: IMessageContentMap[T]
}

interface IMessageContentMap {
[MessageEnum.IMAGE]: string
[MessageEnum.Text]: number
}

let a = <T extends MessageEnum>(p: IMessage<T>) => {}

a({
type: MessageEnum.Text,
value: 2,
})


a({
type: MessageEnum.Text,
value: 2, // Type 'string' is not assignable to type 'number'.
})
noe132
2021-07-26 15:58:29 +08:00
第 5 行写错了,应该是 a.data // string
aguesuka
2021-07-26 16:12:12 +08:00
IMessage 你要的就是是经典的 Dependent pair types (Sigma-type), 它是 dependent type, 中文依值类型, 可以将第一个项作为第二个项的类型 (allow the type of the second component of a pair
to vary depending on the choice of the first component.)
aguesuka
2021-07-26 16:12:52 +08:00
据我所知没有支持依赖类型的工业语言
johnwood
2021-07-26 16:23:19 +08:00
type IMessage =
| {
type: MessageEnum.IMAGE;
value: string;
}
| {
type: MessageEnum.Text;
value: number;
};
WynneChan
2021-07-27 13:09:23 +08:00
@noe132 1 楼大佬这种方式只能用于函数时好像,我目前是把这个定为了一个数组,用了 swtich 去判断 type,这时候就推不出具体的 value 了。
@johnwood 最终还是改用大佬的这种 type 或的形式去做了

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

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

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

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

© 2021 V2EX