Skip to content

Instantly share code, notes, and snippets.

@HendrikPetertje
Created September 10, 2020 08:51
Show Gist options
  • Save HendrikPetertje/dc7adb32326d622fa86bce39fd8b821e to your computer and use it in GitHub Desktop.
Save HendrikPetertje/dc7adb32326d622fa86bce39fd8b821e to your computer and use it in GitHub Desktop.
type asertion and non-null assertion in Typescript

disclaimer: this is dangerous stuff, typescript is pretty good at infering things and you should probably trust that over these funky things

Aserting a type:

You can force typescript to identify a new variable or a resulting variable to be of a specific type

before:
before

Add a magic "as" asertion and our result is now: after

more info: https://basarat.gitbook.io/typescript/type-system/type-assertion

Non-null assertion

Sometimes you would only run a function or render a component if you thought that a specific item in your context is defined. Or you want Typescript to assume that a variable is not null or undefined.

normally you would do:

  getNameFromTask = () => {
    const { task } = this.context; // task is ITask or undefined
    if (!task) return new Error('this should not have happened!')
    return task.name
  }

with the non-null assertion operator you can do this instead:

  getNameFromTask = () => {
    const { task } = this.context; // Task is ITask or undefined;
    return task!.name
  }

The bang here tells typescript that you are 100% sure that the variable will be present.

more info: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator

@HendrikPetertje
Copy link
Author

Modern ECMAScript as well as Typescript also support the "safe operator" which is sort of a reverse on the !.

so if you have the last example:

  getNameFromTask = () => {
    const { task } = this.context; // task is ITask or undefined
    if (!task) return 'no name'

    return task.name
  }

you could instead write that as:

  getNameFromTask = () => {
    const { task } = this.context; // task is ITask or undefined
    return task?.name || 'No name';
  }

?. will only execute the function or read the variable after it when the variable is not null or undefined.
this does not protect from mismatching types though! so task?.functionThatDoesntExists() will throw an error if task is defined.
more info: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment