TypeScript 可选属性不接受未定义的值

Posted

技术标签:

【中文标题】TypeScript 可选属性不接受未定义的值【英文标题】:TypeScript optional properties not accepting undefined value 【发布时间】:2021-08-27 22:39:10 【问题描述】:
<MyCustomField
    type=props.type

MyCustomField 的type 类型定义:

type?: string;

props.type的类型定义:

type?: string;

由于某种原因,我收到此错误:

感觉就像我不小心打开了某些设置。我的 tsconfig:


    "compilerOptions": 
        "target": "es5",
        "lib": [
            "dom",
            "dom.iterable",
            "esnext"
        ],
        "allowJs": false,
        "skipLibCheck": true,
        "noImplicitAny": false,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noFallthroughCasesInSwitch": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx",
    ,
    "include": [
        "src"
    ]

编辑:另外,它编译得很好:

只是 VSCode Intellisense 不喜欢而已。

编辑 2:

if (!clone[index].options) throw Error(`Data at index $index, $optionIndex doesn\'t have options`);
if (type === FieldDataTypeEnum.RadioButton) 
    clone[index].options.forEach(o => o.checked = false);
 else 
    clone[index].options[optionIndex].checked = true;

这也给了我一个错误,说 clone[index].options 可能是未定义的,即使 if 语句应该忽略这一点:

但仍然可以正常编译。

【问题讨论】:

负责的设置大概是"strict": true。我对 React 了解不多,但作为一种猜测,我会说 React 可能将 ?: 解释为仅在属性不存在时才允许未定义。 您能否在沙盒中重现此问题,codesandbox.io ? @AjeetShah 不,就像我说的,这似乎是一个智能感知问题 在这种情况下,您应该尝试更新您的 VSCode,关闭它并重新打开它。 @AjeetShah 我有。 【参考方案1】:

我认为这看起来非常相似:https://***.com/a/64765671/12431728

根据链接的答案,我认为您必须将undefined 指定为道具的可能类型,因此type?: string | undefined 用于道具类型定义。

他们提供的另一个选项是通过将 "strictNullChecks": false 添加到 compilerOptions 来禁用 tsconfig.json 中的严格空检查。

【讨论】:

这很奇怪,虽然我不想跳过空值检查,但我也希望能够将可选变量传递给可选的道具。同一个定义的类型怎么不兼容很奇怪,这感觉更像是一个错误。 IMO 说得通。这不是 React 独有的,而是 TypeScript 本身所独有的。看到这个答案:***.com/a/50491030/12431728 它编译得很好,对我来说这似乎是一个智能感知错误,也许是一个 tsconfig 设置? 它应该可以正常编译,因为在编译时不知道该变量是赋值还是赋值undefined 类似的问题确实会给我编译器错误,但是【参考方案2】:

如评论中所述:

看起来您的 VSCode 和您的脚本使用不同的打字稿版本。您可以在右下角的 VSCode 中选择 TS 版本,同时打开一个 .TS 文件

【讨论】:

【参考方案3】:

对我来说,VSCode 使用的是最新的 Typescript 测试版,而不是我在工作区中声明的版本。

他们的新 Beta 版本的此 PR 引入了一些潜在的重大更改,这就是您看到错误的原因。 https://github.com/microsoft/TypeScript/pull/43947

它引入了一种新的严格模式,--strictOptionalProperties。如果您的 tsconfig 中有 "strict": true,则默认启用此新模式。

有人在这里提出了一个建议,这可能有助于更清楚地说明这一点。 https://github.com/microsoft/TypeScript/issues/44403

总而言之,您在 VSCode 中看到了 Intellisense 问题,因为 VSCode 使用的新版本的 Typescript 引入了重大更改。如果您更改 VSCode Typescript 版本以匹配您的工作区,您应该没问题。

【讨论】:

以上是关于TypeScript 可选属性不接受未定义的值的主要内容,如果未能解决你的问题,请参考以下文章

当没有要指定的确切值“未定义”或“空”时,为 TypeScript 可选参数传递啥? [复制]

为啥“”.abcd 返回未定义的值而不是在 Javascript 中抛出未定义的错误(但 Typescript 抛出警告)

TypeScript 令人困惑的错误'对象可能是'未定义'和'类型上不存在属性'长度''

带有可选参数的 TypeScript lambda 函数

TypeScript给接口添加任意属性

TypeScript深入学习TypeScript对象类型