TypeScript releases are coming thick and fast, so it’s easy to miss some of the handy features that are added. Here are some of the new features that I’ve found useful in the last year.

The unknown type

When dealing with data from a 3rd party library or web API that hasn’t got TypeScript types, we often reach for the any type. However, this means no type checking will occur on the data.

const person: any = await getPerson(id);
const postcode = person.address.postcode; // TypeScript doesn't yell at us but what if there is no address property ... 💥!

The unknown type is a strongly-typed alternative to any in these situations:

const person: unknown = await getPerson(id);
const postcode = person.address.postcode; // 💥 - Type error - Object is of type 'unknown'

The unknown type forces us to do explicit type checks when interacting with it:

const person: unknown = await getPerson(id);
if (isPersonWithAddress(person)) {
  const postcode = person.address.postcode;
}

function isPersonWithAddress(person: any): person is Person {
  return "address" in person && "postcode" in person.address;
}

Readonly arrays

We may think the following would raise a type error:

type Person = {
  readonly name: string;
  readonly scores: number[];
};
const bob: Person = {
  name: "Bob",
  scores: [50, 45]
};

bob.scores.push(60); // does this raise a type error?

TypeScript is perfectly happy with this, though. The readonly keyword before an array property name only ensures the property can’t be set to a different array - the array itself isn’t immutable.

However, we can now put an additional readonly keyword before the array itself to make it immutable:

type Person = {
  readonly name: string;
  readonly scores: readonly number[];
};
const bob: Person = {
  name: "Bob",
  scores: [50, 45]
};
bob.scores.push(60); // 💥 - Type error - Property 'push' does not exist on type 'readonly number[]'

#typescript

6 useful TypeScript 3 features you need to know
1.25 GEEK