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

才知道原来 typescript 最近(4.4.0)才支持区分一个属性不存在还是属性的值为 undefined

  •  
  •   Leviathann · 2021-09-17 16:52:30 +08:00 via iPhone · 1308 次点击
    这是一个创建于 923 天前的主题,其中的信息可能已经有所发展或是发生改变。
    然后就碰到这个点导致的 bug 。。
    多少年了终于能够在编译器发现这个问题,我只能说 thanks for inventing Javascript

    如果有同样需要的朋友可以在 tsconfig 里加
    “exactOptionalPropertyTypes”: true,
    11 条回复    2022-04-23 09:26:42 +08:00
    xlsepiphone
        1
    xlsepiphone  
       2021-09-17 17:11:14 +08:00
    语法上如何判断呢?
    number
        2
    number  
       2021-09-17 17:14:06 +08:00
    能否举个开启前和开启后的栗子
    learningman
        3
    learningman  
       2021-09-17 17:18:12 +08:00 via Android
    Object.hasOwnProprietor
    learningman
        4
    learningman  
       2021-09-17 17:18:21 +08:00 via Android
    Property
    xlsepiphone
        5
    xlsepiphone  
       2021-09-17 17:29:28 +08:00
    ```typescript
    // With 'exactOptionalPropertyTypes' on:
    const p: Person = {
    name: "Daniel",
    age: undefined, // Error! undefined isn't a number
    };
    ```
    EPr2hh6LADQWqRVH
        6
    EPr2hh6LADQWqRVH  
       2021-09-17 17:37:07 +08:00
    搞错了,是人的问题。

    这个选项可有可无,我个人觉得没有更好一点。

    都已知存在这个字段了,还非得掩耳盗铃假装它不存在,不能给他设置成 undefined,
    那怎么办,只能 delete 他?
    手动设置一个 undefined 可选项?
    这两个都比现在的方式更麻烦更不可读。
    Leviathann
        7
    Leviathann  
    OP
       2021-09-17 17:43:09 +08:00
    @number
    @xlsepiphone

    开启后可以判断一个 obj 是没有字段还是字段的值为 undefined,
    如果不开,当你遍历这个 obj 的 entries 的时候,如果定义的时候使用的是 {propertyName?: string | number } 编译器不会告诉你这个 value 可能是 undefined

    开了以后就能识别出来
    type A = { name?: string }
    const a: A = { name: undefined } // error
    maichael
        8
    maichael  
       2021-09-17 18:23:32 +08:00
    @avastms #6

    "Functions and operators like Object.assign, Object.keys, object spread ({ ...obj }), and for–in loops behave differently depending on whether or not a property actually exists on an object."

    基于官方的说法,这个场景更多针对于下面这类的用法:
    const a = {b:1, c:undefined}
    object.keys(a) // ['b', 'c']
    const b = {b:1}
    object.keys(b) // ['b']

    当然,意义确实不大。
    pkoukk
        9
    pkoukk  
       2021-09-17 18:43:36 +08:00
    是啥情况下需要传值为 undefined 呢?想传空应该传 null 吧
    Leviathann
        10
    Leviathann  
    OP
       2021-09-17 19:16:07 +08:00
    @pkoukk
    就是比如说有一个 react component 的属性 name,定义是 {name?: string},不传的时候就自然是 undeifined,然后用这个属性的字面量简写构建了一个对象
    const obj = {name}
    把这个 obj 传给一个接收参数类型为 {params: {name?: string}} 的函数,然后函数直接
    Object.entries.map(([key, value]) => xxx)
    然后由于不开这个选项,value 就没有告诉他可能是 undefined,结果我用的时候也没注意到,然后还得帮他改 bug 。。
    iugo
        11
    iugo  
       2022-04-23 09:26:42 +08:00
    在运行时上有意义, 但在编译时上意义没那么大.

    在运行时上的意义比如 Object.keys() 时的结果.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5738 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 06:24 · PVG 14:24 · LAX 23:24 · JFK 02:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.