Closed
Description
Search Terms
condition property if in guard
Suggestion
I would like the following to work:
function f(x: { a: string }|{ b: string }) {
if (x.a) {
// x should be { a: string } here
}
}
Use Cases
This is very common pattern in JavaScript, so when rewriting some of my JS code to TypeScript I often have to change this.
E.g.
function logError(e: Error|TaskError) {
if (e.fromTask) {
// TaskError, log fromTask
}
else {
// other error, simple log
}
...
}
I can rewrite this in two ways.
First
if ('fromTask' in e)
This has two issues:
- It does not check that at least one of union types has
fromTask
, so if I made a typo (fromTsk
) it would not be found. - It looks unnatural -- there is probably some JS pattern that recommends this over a shorter check, but I haven't seen it used much
Second
function logError(e: (Error & { fromTask?: undefined })|TaskError)
This works, but feels really artificial -- it does not give any information that previous signature didn't have, and the only purpose is to work around the if
error.
Examples
Union
interface I1 { a: string }
interface I2 { b: string }
interface I3 { a?: string; b: string }
function f(x: I1|I2|I3) {
if (x.a) {
// type of x should be I1|(I3 & { a: string })
}
}
No such property
interface I1 { a: string }
interface I2 { b: string }
function f(x: I1|I2) {
if (x.c) { // should fail to compile as `c` is not present on either I1 or I2
}
}
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.