代码之家  ›  专栏  ›  技术社区  ›  Zachiah

为什么在打字稿中设置动态键是不健全的

  •  2
  • Zachiah  · 技术社区  · 6 月前

    背景/复制

    type Example = {
        a: string,
        b: number
    }
    
    
    let value: Example = {
        a: 'hello',
        b: 10,
    }
    
    // This IIFE is because typescript will narrow the type if assigned directly like
    // const k: keyof Example = 'a'
    const k = ((): keyof Example => 'a')()
    
    value = {
        ...value,
        // Obviously this is unsound
        [k]: 5,
    }
    

    即使在严格模式下,这也会通过。 Playground link .

    提问

    为什么这里的打字稿不健全?我想了解总体的不安全性,这样我就可以避免使用这样的不类型安全的模式。我也非常感谢任何相关文档或GitHub问题。

    1 回复  |  直到 6 月前
        1
  •  3
  •   jcalz    6 月前

    这是TypeScript的一个已知问题,记录在 microsoft/TypeScript#38663 如果你有 computed property name 其类型为 union ,那么TypeScript将把该类型一直扩展到 string (参见 microsoft/TypeScript#13948 ),然后或多或少完全忽略了该属性。也就是说,这比分配一个 number a ,它可以分配 任何东西 ,包括 false (参见 this playground link ).

    它目前还没有被归类为bug,可能是因为这种属性写入的不健全渗透到了语言中:

    // widen the type of value, this is considered "safe"
    const myVal: { [k: string]: string | number } = value;
    
    // but oops:
    myVal.b = "oopsieDoodle";
    

    修复这种不健全会使事情更安全,但可以说使用起来更烦人,正如许多关于 microsoft/TypeScript#30769 TypeScript是不健全的,主要是在TS团队认为治愈比疾病更糟糕的地方。请参阅 TypeScript Language Design Non-Goal #3 TS团队的评论 microsoft/TypeScript#9825 .