While working on tests, I encountered a situation where my type validation code behaves differently based on its placement within the codebase. Specifically, when I have my error-throwing type validation code within the same function, Typescript is able to detect and handle it without any issues.
However, when I extract the type validation code into a separate function, Typescript starts throwing errors related to properties not existing, such as
Property 'vehicle' does not exist on type 'SomeParentType'
.
For example, the following code works as expected:
function appendToOutputString(obj: SomeParentType) {
if (!isChildTypeA(obj)) {
throw new Error("Must be of type ChildA!");
}
outputString += obj.vehicle;
}
But this alternative approach does not work:
function appendToOutputString(obj: SomeParentType) {
expectIsChildTypeA(obj)
outputString += obj.vehicle;
}
If you'd like to view the complete code, you can do so by following this link: https://stackblitz.com/edit/checking-type-in-function?file=index.ts
Alternatively, you can refer to the snippet provided below:
interface SomeParentType {
title: string;
}
interface SomeChildTypeA extends SomeParentType {
vehicle: string;
}
interface SomeChildTypeB extends SomeParentType {
animal: string;
}
let outputString = "";
function isChildTypeA(childType: SomeParentType): childType is SomeChildTypeA {
return "vehicle" in childType;
}
function expectIsChildTypeA(obj: any) {
if (!isChildTypeA(obj)) {
throw new Error("Must be of type ChildA!");
}
}
function appendToOutputString(obj: SomeParentType) {
// if (!isChildTypeA(obj)) {
// throw new Error("Must be of type ChildA!");
// }
expectIsChildTypeA(obj)
outputString += obj.vehicle; // Typescript complains!!
}
// Write TypeScript code!
const appDiv: HTMLElement = document.getElementById("app");
appDiv.innerHTML = `<h1>${outputString}</h1>`;