Search code examples
typescripttry-catch

Error object inside catch is of type unknown


I have the following code:

try {
  phpDoc(vscode.window.activeTextEditor);
} catch (err) {
  console.error(err);
  vscode.window.showErrorMessage(err.message);
}

however err.message gets the error Object is of type 'unknown'.ts(2571) on err., but I cannot type the object in catch (err: Error).

What should I do?


Solution

  • As a supplementary answer to CertainPerformance's one:

    Up until TypeScript 4.0, the catch clause bindings were set to any thus allowing easy access to the message property. This is unsafe because it is not guaranteed that what's thrown will be inheriting from the Error prototype - it just happens that we don't throw anything but errors as best practice:

    (() => {
        try {
            const myErr = { code: 42, reason: "the answer" };
            throw myErr; //don't do that in real life
        } catch(err) {
            console.log(err.message); //undefined
        }
    })();
    

    TypeScript 4.0 introduced an option for a safer catch clause by allowing you to annotate the parameter as unknown, forcing you to either do an explicit type assertion or, even better, to type guard (which makes the clause both compile-time and runtime-safe).

    However, to avoid breaking most of the codebases out there, you had to explicitly opt-in for the new behavior:

    (() => {
        try {
            throw new Error("ouch!");
        } catch(err: unknown) {
            console.log(err.message); //Object is of type 'unknown'
        }
    })();
    

    TypeScript 4.4 introduced a new compiler option called useUnknownInCatchVariables that makes this behavior mandatory. It is false by default, but if you have the strict option turned on (as you should), it is turned on which is most likely the reason why you got the error in the first place.