How to do try catch and finally statements in TypeScript?
Solution 1:
Edit
Typescript 4.0 added the ability to specify unknown
and any
on catch variables (Issue) And typescript 4.4 added the ability to make unknown
the default on catch variables (PR) uning the useUnknownInCatchVariables
flag.
With this flag the following is now possible:
catch(e){
result = e.message; // error under useUnknownInCatchVariables
if (typeof e === "string") {
e.toUpperCase() // works, `e` narrowed to string
} else if (e instanceof Error) {
e.message // works, `e` narrowed to Error
}
}
Specifying arbitrary types on catch variables is still not supported.
Original answer
Typescript does not support annotations on the catch variable. There is a proposal to allow this but it is still being discussed (see here)
Your only solution is to use a type assertion or an extra variable
catch(_e){
let e:Error= _e;
result = e.message;
}
catch(e){
result = (e as Error).message;
}
Unfortunately this will work as well and is completely unchecked:
catch(e){
result = e.MessageUps;
}
Note
As you can read in the discussion on the proposal, in JS not everything that is thrown has to be an Error
instance, so beware of this assumption
Maybe tslint with no-unsafe-any
would help catch this.
Solution 2:
With TypeScript 4.0, you can set unknown
as catch clause variable type:
unknown
is safer thanany
because it reminds us that we need to perform some sorts of type-checks before operating on our values. (docs)
try { /* ... */ }
catch (e: unknown) { // <-- note `e` has explicit `unknown` type
e.message // errors
if (typeof e === "string") {
e.toUpperCase() // works, `e` narrowed to string
} else if (e instanceof Error) {
e.message // works, `e` narrowed to Error
}
// ... handle other error types
}
Playground
Update: TypeScript 4.4 provides a config flag --useUnknownInCatchVariables
to let catch-variables default to type unknown
. This is also automatically enabled with the --strict
flag.
Solution 3:
Firstly, you need to define the result
variable
let result;
Secondly, you can't define the type of e - as the message said, so in case you want to force the type of e, use
catch(e){
result = (e as Exception).Message;
}
or
catch(e){
result = (<Exception>e).Message;
}
Otherwise, it should still work because e will have the type as any
catch (e) {
result = e.Message;
}