Home > Enterprise >  How to tell TS that the property exists
How to tell TS that the property exists

Time:08-17

I am looking for a way to tell Typescript that the property I'm trying to access is not null/undefined.

I'm aware of

  • ? optional chain operator
  • ! non-null assertion operator

Here is what I'm trying to do

type UpsertRequestType = {
  per_page?: number;
  page_window?: number;
};

type SettingsCollectionType = {
  _id: string;
  per_page: number;
  page_window: number;
};

class Settings {
  constructor(private readonly settingsRepository: Mongo.Collection<SettingsCollectionType>) {}

  private get settings() {
    return this.settingsRepository.findOne({}) || null;
  }

  upsert(payload: Optional<UpsertRequestType>): void;
  upsert(payload: Required<UpsertRequestType>): void;
  upsert(payload: unknown): void {
    if (this.settings) return this.update(<Optional<UpsertRequestType>>payload);

    return this.insert(<Required<UpsertRequestType>>payload);
  }

  private update(payload: Optional<UpsertRequestType>): void {
    this.settingsRepository.update({ _id: this.settings!._id }, { $set: payload });
  }

  private insert(payload: Required<UpsertRequestType>): void {
    this.settingsRepository.insert(payload);
  }
}

As you can see I am using this.settings!._id with ! symbol to clarify that _id is there for sure. However, is there another way that TS can infer this behavior automatically?

It is pretty obvious that when I check if(this.settings) it is not definitely null/undefined

CodePudding user response:

In this case the this.settings!._id is inside the update method, and the method is called inside the if statement, but TypeScript cannot be sure that you will never call update outside of it, thus it considers that this.settings might be undefined.

I don't think that you have an easy way of avoiding the ! syntax, so I would probably just keep it as it is now.

CodePudding user response:

As you wrote it, you are specifying that this.settings exists, what you want to actually do is:

this.settings!._id! so you specify that both settings and _id are not null (or undefined).

The exclamation mark operator is always put after the property you want to assert is not null, for a very specific reason:

let temp?: number = null

/*code happens here*/
if(temp! < 3)
// ...

In this case you couldn't really do something like: this!.temp

CodePudding user response:

In your particular case, the settings() getter could be null. You should specify the return value of the get function to be non-nullish so you won't need to use the ! operator.

  • Related