Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Boolean truthiness narrowing not working in Typescript

I’ve checked similar questions and cannot find any examples like mine. I am using a function to narrow down a boolean option in an if/else clause, but it only works when defined explicitly, not using the function.

Here is the code I am working with—

TYPES

type SimpleCellContent = string | number;
type ComplexCellContent = {
  content: SimpleCellContent;
  formatter: (content: any) => string;
  class?: string;
  link?: string;
  linkClass?: string;
};
type CellContent = SimpleCellContent | ComplexCellContent;

LOGIC

const isSimpleContent = (cellData: CellContent) => {
  return typeof cellData === 'string' || typeof cellData === 'number' || typeof cellData === 'undefined';
};

const extractContent = (cellData: CellContent) => {
  if (isSimpleContent(cellData)) {
    return cellData;
  } else if (typeof cellData.content !== 'undefined') { // <---  ERROR !!! 🚨
    return cellData.content;
  } else {
    throw new Error('Invalid cell data: ' + JSON.stringify(cellData));
  }
};

The error reads…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Property 'content' does not exist on type 'CellContent'.
  Property 'content' does not exist on type 'string'. ts(2339)

However, if I switch isSimpleContent(cellData) to be the exact same return value of the previous function (typeof cellData === 'string' || typeof cellData === 'number' || typeof cellData === 'undefined'), it works without an issue.

Why wouldn’t this work the same way when using a function?

>Solution :

Unless there are new developments in the language, a function only becomes a type guard, if you explicitly mark it in the return type:

const isSimpleContent = (cellData: CellContent): cellData is SimpleCellContent => {
  return typeof cellData === 'string' || typeof cellData === 'number' || typeof cellData === 'undefined';
};

Docs:
https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading