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.