3

I want to change how object is filled with properties.

Currently I have

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

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

And function which creates an object looks like this:

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

I have tried to change my code to

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

and VS code IDE does not see any issues e.g: when I mouse over the:

  • data. it says const data: INewOffer

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

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

but when I run test I have error:

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

I have tried setting it like: data.employment!.wage = newCustomer.wage

but it does not work. Then I have found out that there is no support in typescript for Optional Chaining.

and my question is, why IDE does not says its an error? or maybe I have to do something else to make it work?

Owczarkov
  • 31
  • 1
  • 2
  • See https://stackoverflow.com/questions/51741333/optional-chaining-operator-support-in-vscode with v1.41 – Mark Dec 07 '19 at 21:14

2 Answers2

2

You should make sure to enable --strictNullChecks, a compiler option. Presumably you've got a tsconfig.json file in your project; you should specify it there. In fact, I recommend using --strict, which includes --strictNullChecks plus other helpful stuff. That should hopefully start warning you with errors like this:

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

Adding the exclamation point will not help; it is a non-null assertion, which means you are telling the compiler that even though it thinks the object might be undefined, you are sure that it's not. This is basically the opposite of the problem you have. If you do this:

   data.employment!.wage // no error now

it will suppress the error that --strictNullChecks turns on, but explode at runtime since you lied to the compiler. That assertion is meant for situations like this:

// 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's type system exists only at design time (when you write the program) and is completely erased from the emitted JavaScript that runs. If you want a runtime check to happen, you need to write that runtime check, and let TypeScript's type checker verify that you have done so:

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

TypeScript does try to provide implementations for proposed JavaScript features, and there may eventually be support for optional chaining in JavaScript, but the current proposal is only at Stage 1, and the TypeScript maintainers' general policy is only to implement language additions once they reach Stage 3. So TypeScript doesn't support optional chaining yet as of TS3.4.

Okay, hope that helps. Good luck!

jcalz
  • 264,269
  • 27
  • 359
  • 360
  • Thank you a lot for clarification that is exactly what I was looking for. I could addd that in my tsconfig file I have: `"strict": true,` but also `"strictNullChecks": false,` – Owczarkov Apr 05 '19 at 14:44
2

Finally typescript supports optional chaining - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html

So you could update the typescript version to 3.7 or later and update the version of vscode to make it working.

Archit Garg
  • 2,908
  • 2
  • 14
  • 22