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

一个类型体操的问题,我能不能既要又要?

  •  
  •   TWorldIsNButThis · 2022-07-19 15:09:47 +08:00 · 1888 次点击
    这是一个创建于 856 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想指定一个 object 的 value 限定为某几个 string literal 其中之一,key 不限制,但是最终得到的类型是 const 的 比如

    type ValidValue = 'a' | 'b' | 'c'
    
    const obj = {
      xxx1: 'a',
      xxx2: 'b',
      xxx3: 'c',
      xxx4: 'd' // 报错
    }
    
    

    并且这个 obj 最后推导出来的类型为 { xxx1: 'a', xxx2: 'b', xxx3: 'c' } 而不是 Record<string, ValidValue> 这种宽泛的定义?

    7 条回复    2022-07-19 18:15:33 +08:00
    anjianshi
        1
    anjianshi  
       2022-07-19 15:17:14 +08:00
    const obj = { x1: 'a', x2: 'b', x3: 'c' } as const
    就行了?
    TWorldIsNButThis
        2
    TWorldIsNButThis  
    OP
       2022-07-19 15:24:14 +08:00
    @anjianshi 但是这个不能阻止 x4: 'd' 这个不合法的值
    noe132
        3
    noe132  
       2022-07-19 15:28:55 +08:00
    type Keys = 'xxx1' | 'xxx2' | 'xxx3'
    type Obj = Record<Keys, ValidValue>
    TWorldIsNButThis
        4
    TWorldIsNButThis  
    OP
       2022-07-19 15:43:33 +08:00
    @noe132 这个拿到的类型就不是 const 的了,typeof obj['xxx1']不是 'a' 而是 'a' | 'b' | 'c',
    aguesuka
        5
    aguesuka  
       2022-07-19 17:49:22 +08:00   ❤️ 2
    type ValidValue = 'a' | 'b' | 'c'
    const obj = (<T extends Record<any, ValidValue>>(_ : T): T => _)({
    xxx1: 'a',
    xxx2: 'b',
    xxx3: 'c',
    })
    TWorldIsNButThis
        6
    TWorldIsNButThis  
    OP
       2022-07-19 18:13:20 +08:00
    @aguesuka 卧槽 牛逼👍 这是啥原理, 立即执行函数吗
    aguesuka
        7
    aguesuka  
       2022-07-19 18:15:33 +08:00
    @TWorldIsNButThis 定义一个返回参数的 lambda 然后执行它.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3405 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:53 · PVG 18:53 · LAX 02:53 · JFK 05:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.