Skip to content

Instantly share code, notes, and snippets.

@OliverJAsh
Created August 2, 2019 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverJAsh/56611a99d80f662e2bdc0eb75673c9be to your computer and use it in GitHub Desktop.
Save OliverJAsh/56611a99d80f662e2bdc0eb75673c9be to your computer and use it in GitHub Desktop.
TypeScript narrow non-discriminated union
{
type AncestryType = {
type: string;
};
type AncestryCategory = {
type: string;
category: string;
};
type AncestrySubcategory = {
type: string;
category: string;
subcategory: string;
};
type Ancestry = AncestryType | AncestryCategory | AncestrySubcategory;
const fn1 = (ancestry: Ancestry) => {
if (!('category' in ancestry)) {
ancestry; // ✅ AncestryType
} else {
// ✅ AncestryCategory | AncestrySubcategory
ancestry;
}
};
const checkAncestryIsType = (ancestry: Ancestry): ancestry is AncestryType =>
!('category' in ancestry);
const fn2 = (ancestry: Ancestry) => {
if (checkAncestryIsType(ancestry)) {
ancestry; // ✅ AncestryType
} else {
/*
Actual: never
Expected: AncestryCategory | AncestrySubcategory
*/
ancestry;
}
};
}
//
// Workaround
// https://github.com/microsoft/TypeScript/issues/32680#issuecomment-517726428
//
{
type AncestryType = {
_type: 'type';
type: string;
};
type AncestryCategory = {
_type: 'category';
type: string;
category: string;
};
type AncestrySubcategory = {
_type: 'subcategory';
type: string;
category: string;
subcategory: string;
};
type Ancestry = AncestryType | AncestryCategory | AncestrySubcategory;
const checkAncestryIsType = (ancestry: Ancestry): ancestry is AncestryType =>
!('category' in ancestry);
const fn1 = (ancestry: Ancestry) => {
if (checkAncestryIsType(ancestry)) {
ancestry; // ✅ AncestryType
} else {
ancestry; // ✅ AncestryCategory | AncestrySubcategory
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment