I have the following function:
/**
* Retrieves a component template from filesystem
*/
const getComponentTemplate = async (
p: string
): Promise<string> => {
let template: string
try {
template = await fs.readFile(p, {
encoding: 'utf8'
})
} catch (e) {
if (e instanceof Error && e.code === 'ENOENT') {
throw new Error(`template for element type ${elementType} not found`)
}
throw e
}
return template
}
Typescript complains here:
[ts] Property 'code' does not exist on type 'Error'
This is because the Javascript Error class only has properties message and name.
However, Node's Error class does have a code property.
Typescript defines this in a special interface ErrnoException (see source here). I have added @types/node to my package.json, but this didn't make Typescript realize that this Error is part of the ErrnoException interface.
It is not possible to declare a type annotation in a catch clause. So, how does one make the Typescript compiler able to resolve that this is a Node Error?
FYI, this is part of my tsconfig.json:
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"lib": ["es2017"]
...
}
}
e instanceof Erroryou're testing to see if it's anErrornot anErrnoException. I'm not sure on the best way to tell it the right type, but a "quick n dirty" way ise instanceof Error && (e as ErrnoException).code === 'ENOENT'.function isError(error: any): error is ErrnoException { return error instanceof Error; }though it'd surprise me if something like that doesn't already exist. You'd this this would be a common requirement!asbut this seems somewhat dirty. Shouldn't Typescript know that I am running in Node?if (e instanceof ErrnoException)just fit your needs?Error(the one provided by Node).ErrnoExceptionis only an interface, not a class. Therefore e is not an instance of it. Note that Node'sErrorimplementsErrnoException, but for some reason Typescript doesn't realize this.