Description
Search Terms
conditional else exclude narrow
Suggestion
TypeScript should infer Exclude
types in conditional expressions and statements.
Specifically, whenever the positive branch (if
, or the x
in c ? x : y
) has a more specific type thanks to a type guard, the negative branch (else
/y
) should have the relevant Exclude
type.
Use Cases
This would provide a natural way to infer Exclude
types and it would generalise in a natural way the current behaviour of conditional statements over union and finite-domain types.
Apparently right now the only way to have a value of type Exclude
is to assert it manually (either through type guards or type assertions).
Examples
function partition<A, B extends A>(items: A[], f: (x: A) => x is B): [B[], Array<Exclude<A, B>>] {
const bs: B[] = [];
const others: Array<Exclude<A, B>> = [];
for (const x of items) {
if (f(x)) {
bs.push(x);
} else { // with the proposed feature, x: Exclude<A, B> in this branch
others.push(x); // while currently this fails because TSC infers x: A
}
}
return [bs, others];
}
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behaviour 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.
I am unsure if this could break existing code.
Making the typing more accurate could reveal dead code, which could result in compilation errors.