【问题标题】:How to use Optional Chaining in TypeScript?如何在 TypeScript 中使用可选链?
【发布时间】:2019-08-27 05:59:44
【问题描述】:

我想更改对象填充属性的方式。

目前我有

export interface INewOffer {
    employment?: IEmployment;
    heightWeight?: IHeightWeight;
}

export interface IEmployment{
    trainings?: string;
    activeEmployment?: string;
    wage?: string;
}

创建对象的函数如下所示:

private dataGenerator(newCustomer: INewCustomer): INewOffer {
    const data: INewOffer = {};
    if (NullCheck.isDefinedOrNonNull(newCustomer.age)) {
        data.employment = {
            trainings: newCustomer.trainings,
            activeEmployment: newCustomer.activeEmployment,
            wage: newCustomer.wage,
        };
    } else {
        data.employment = {
            wage: newCustomer.wage,
            };
        }
    data.heightWeight = {
        height: '180',
        weight: '75',
    };
    return data;
}

我已尝试将我的代码更改为

private dataGenerator(newCustomer: INewCustomer): INewOffer {
    const data: INewOffer = {};
    if (NullCheck.isDefinedOrNonNull(newCustomer.age)) {
            data.employment.trainings = newCustomer.trainings;
            data.employment.activeEmployment = newCustomer.activeEmployment;
            data.employment.wage = newCustomer.wage
    } else {
           data.employment.wage = newCustomer.wage
    }
    data.heightWeight.height = '180';
    data.heightWeight.weight = '75';

    return data;
}

VS 代码 IDE 看不到任何问题,例如:当我将鼠标悬停在:

  • data. 上面写着const data: INewOffer

  • employment. => (property) INewOffer.employment?: IEmployment

  • wage => (property) IEmployment.wage?: string

但是当我运行测试时出现错误:

E/launcher - Error: TypeError: Cannot set property 'wage' of undefined

我尝试将其设置为: data.employment!.wage = newCustomer.wage

但它不起作用。然后我发现 typescript 不支持 Optional Chaining。

我的问题是,为什么 IDE 没有说它是一个错误?还是我必须做些其他事情才能让它发挥作用?

【问题讨论】:

标签: typescript visual-studio-code protractor


【解决方案1】:

您应该确保启用--strictNullCheckscompiler option。大概你的项目中有一个tsconfig.json 文件;你应该在那里指定它。事实上,我推荐使用--strict,其中包括--strictNullChecks 以及其他有用的东西。这应该有望开始警告你这样的错误:

   data.employment.wage // error!
// ~~~~~~~~~~~~~~~ <-- Object is possibly undefined.

添加感叹号无济于事;它是non-null assertion,这意味着您告诉编译器即使it 认为该对象可能是未定义的, 确信它不是。这基本上与您遇到的问题相反。如果你这样做:

   data.employment!.wage // no error now

它将抑制--strictNullChecks 开启的错误,但由于您对编译器撒谎,因此在运行时会爆炸。该断言适用于以下情况:

// this ends up setting data.employment to {} but the compiler doesn't realize it
   Object.assign(data, { employment: {} }); 

   data.employment.wage // error!  but we know it *is* defined
// ~~~~~~~~~~~~~~~ <-- Object is possibly undefined.

   data.employment.wage // no error now

TypeScript 的类型系统仅在设计时(编写程序时)存在,并且完全来自运行的发出的 JavaScript 的erased。如果您希望进行运行时检查,则需要编写该运行时检查,并让 TypeScript 的类型检查器验证您是否已这样做:

  data.employment = {}; // set the property in a way the compiler recognizes
  data.employment.wage; // no error now

TypeScript确实尝试为提议的 JavaScript 功能提供实现,并且可能最终在 JavaScript 中支持 optional chaining,但目前的提议仅在 Stage 1,TypeScript 维护者的一般策略是仅在达到第 3 阶段后才实施语言添加。因此,TypeScript 从 TS3.4 开始不支持可选链接 yet

好的,希望对您有所帮助。祝你好运!

【讨论】:

  • 非常感谢您的澄清,这正是我想要的。我可以在我的 tsconfig 文件中添加:"strict": true,,还有"strictNullChecks": false,
【解决方案2】:

最后 typescript 支持可选链接 - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html

因此您可以将 typescript 版本更新到 3.7 或更高版本,并更新 vscode 的版本以使其正常工作。

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 2020-03-24
    • 2021-10-31
    • 2020-01-24
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多