Narrow Types

Refs:

Why Narrow Types

When encountering some union types 'a' | 'b' | { c: '3'}, we need to do sth with one specific type.

How

if or switch

TS compiler is smart enough to narrow down union types through if or switch

Notice: when in the default case and all types was cased, the type would be never

Using typeof

Use typeof to tell TS type.

instanceof or in

type Movie = {
  title: string;
  releaseDate: Date | string;
  runtime: number;
};
 
type Show = {
  name: string;
  episodes: {
    releaseDate: Date | string;
    title: string;
    runtime: number;
  }[];
};
 
function getDuration(media: Movie | Show) {
  if ("runtime" in media) {
    return media.runtime;
  } else {
    return media.episodes.reduce((sum, { runtime }) => sum + runtime, 0);
  }
}
 
function getPremiereYear(media: Movie | Show) {
  const releaseDate =
    "releaseDate" in media ? media.releaseDate : media.episodes[0].releaseDate;
 
  if (releaseDate instanceof Date) {
    // detect an instance of Date
    return releaseDate.getFullYear();
  } else {
    return new Date(releaseDate).getFullYear();
  }
}

Predict type

function isValidFood(food: string | null): food is string {
  return food !== null;
}

Use utility types NonNullable

const isNotNullish = <T>(value: T): value is NonNullable<T> => value != null;

Truthiness narrowing

When narrowing/excluding falsy type, just tell TS the truth case.

Use &&, ||, !, ...

Exclude

Once I use Exclude to narrow a specific type. Nice.