Specifically, I'd like to use the "fileName" and other extra properties on the Error object in FireFox.
But something like this gives me red underlining, which I could simply ignore, but it bothers me. I tried
function normalizeError(e:Error|ErrorEvent|PromiseRejectionEvent|any) {
if(e instanceof Error){
return {
line: e?.fileName //underlined
}
}else return null
}
This is underlined because fileName is a property only found in a subset of browsers and it is not stanardized, but it is on the Error object which I have specified in the argument type.
Modifying the interface with declaration merging works sort of...
interface Error {
fileName?: string
}
function normalizeError(e:Error|ErrorEvent|PromiseRejectionEvent|any) {
if(e instanceof Error){
return {
line: e?.fileName // Not-underlined
}
}else return null
}
But.. when I export the function, it underlines it again?... Why?
interface Error {
fileName?: string
}
// Exported now:
export function normalizeError(e:Error|ErrorEvent|PromiseRejectionEvent|any) {
if(e instanceof Error){
return {
line: e?.fileName // underlined again
}
}else return null
}
An image to show the underline:
So why doesn't declaration merging work anymore when I export the function? What can I do to remove the underlining?
Addendum 1:
I noticed that if I reassign e to itself, there is no longer an error... What? See:
Apparently assigning e to e changes it from an Error type to an "any" type, which gets rid of the property does not exist error. I would have assumed that the type wouldn't change when essentially assigning it to itself, but I guess I assumed wrong.
Addendum 2:
I think I'm just going to use // @ts-ignore
until someone clarifies the proper way of clarifying to Typescript that the properties might actually be available.
As I mentioned in the comment, an interesting approach as shown in this link is used to make the type-checker happy in a case like this: an abstract class extending the class of your object.
declare abstract class Error extends globalThis.Error {
public fileName: string
// (...)
}
I consider this a better option than overwriting your type declaration globally for two reasons: