如何在TypeScript中使用可选链?

3
我希望您能够修改对象填充属性的方式。
目前我的代码是:
export interface INewOffer {
    employment?: IEmployment;
    heightWeight?: IHeightWeight;
}

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

创建一个对象的 And 函数看起来像这样:

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;
}

当我将鼠标悬停在以下内容时:

  • 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没有显示错误?还是我需要做其他的事情来使它起作用?


请参阅 https://dev59.com/mVUK5IYBdhLWcg3wgQDd,版本为v1.41。 - Mark
2个回答

2

2
你应该确保启用--strictNullChecks,这是一种编译器选项。假设你的项目中有一个tsconfig.json文件,你应该在那里指定它。实际上,我建议使用--strict,它包括--strictNullChecks和其他有用的东西。这应该会开始警告你出现像这样的错误:
   data.employment.wage // error!
// ~~~~~~~~~~~~~~~ <-- Object is possibly undefined.

在这段文字中,加上感叹号是没有帮助的。它是一个非空断言,这意味着你告诉编译器,即使它认为该对象可能未定义,你确定它不是。这基本上与你所遇到的问题相反。如果你这样做:
   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中擦除。如果您想要进行运行时检查,您需要编写该运行时检查,并让TypeScript的类型检查器验证您已经这样做了。
  data.employment = {}; // set the property in a way the compiler recognizes
  data.employment.wage; // no error now

TypeScript尝试为提议的JavaScript功能提供实现,可能最终会支持JavaScript中的可选链接,但当前提案仅处于第1阶段,TypeScript维护者的一般政策是只有当它们达到第3阶段时才实现语言添加。因此,截至TS3.4,TypeScript不支持可选链接。希望这可以帮助您。祝好运!

非常感谢您的澄清,这正是我所需要的。 我可以在我的tsconfig文件中添加: "strict": true, 但同时也有 "strictNullChecks": false, - Owczarkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接