V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
WynneChan
V2EX  ›  TypeScript

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

  •  
  •   WynneChan · 2021-07-26 15:18:25 +08:00 · 1297 次点击
    这是一个创建于 1201 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大佬,假设有这样一个 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; }

    6 条回复    2021-07-27 13:09:23 +08:00
    noe132
        1
    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
        2
    noe132  
       2021-07-26 15:58:29 +08:00
    第 5 行写错了,应该是 a.data // string
    aguesuka
        3
    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
        4
    aguesuka  
       2021-07-26 16:12:52 +08:00
    据我所知没有支持依赖类型的工业语言
    johnwood
        5
    johnwood  
       2021-07-26 16:23:19 +08:00
    type IMessage =
    | {
    type: MessageEnum.IMAGE;
    value: string;
    }
    | {
    type: MessageEnum.Text;
    value: number;
    };
    WynneChan
        6
    WynneChan  
    OP
       2021-07-27 13:09:23 +08:00
    @noe132 1 楼大佬这种方式只能用于函数时好像,我目前是把这个定为了一个数组,用了 swtich 去判断 type,这时候就推不出具体的 value 了。
    @johnwood 最终还是改用大佬的这种 type 或的形式去做了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3005 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:54 · PVG 18:54 · LAX 02:54 · JFK 05:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.