Reputation: 6119
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—
type SimpleCellContent = string | number;
type ComplexCellContent = {
content: SimpleCellContent;
formatter: (content: any) => string;
class?: string;
link?: string;
linkClass?: string;
};
type CellContent = SimpleCellContent | ComplexCellContent;
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…
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?
Upvotes: 1
Views: 431
Reputation: 13807
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
Upvotes: 4