Description
Conditional Type Narrowing
-
Today, we check an expression like
arg === 1 ? "someString" : 37
by getting the type of both branches and unioning them - and we can't make a determination about how either branch corresponds to the condition.
-
In the experimental PR, each branch is checked the expected type.
-
This is a breaking change, but it catches some desirable breaks.
-
For example:
// Currently the expression's type is `any` and we check that against `number`, // but checked individually, the `string` is correctly caught. let x: number = arg === 1 ? "someString" : getAnAny() as any;
-
-
Breaks?
- Most are true bugs
- Good chunk are moves in error positions (breaks
ts-expect-error
) - Some unlikely to be real bugs.
-
The motivation was conditional type narrowing - if you think of first principals, you could consider that the conditional expression creates a conditional type.
- Not too hard to do, but
-
Need to be able to "crack into" each branch of the conditional type for the
return
statement case as well. -
You also might not get the "right" conditional type. For example
function f(x: T): T extends string ? string : number { return x === undefined ? someString : someNumber; }
- Do you end up synthesizing
T extends string ? ... : ...
or do you createT extends undefined ? ... : ...
?
- Do you end up synthesizing
-
Also, error messages won't be quite as good.
-
- Not too hard to do, but
-
Out of time
Slim AST Experiments with Shared Structs in the Compiler
-
Partially inspired by Make AST nodes monomorphic. #59190
-
Uses flagged functionality for
SharedStruct
s via API (no syntax for shared structs yet). -
Idea: every Node is has single a fixed layout.
- Also experimenting with a version that uses shared structs.
-
Separately: a different experiment Uses a "slim AST" which creates a facade to the real AST for API compat.
-
Experimental parser that uses this.
-
You get a speed-up similar to Make AST nodes monomorphic. #59190, though it's at the expense of more memory.
- Much more (why?)
-
If you use shared structs as the backing store for the slim AST, you lose some speed (we anticipate more optimizations with collaboration from V8), but possibly win back some memory and are able to run across multiple threads and you get a net perf win.
Node Type Allocation Source Time (seconds) Current AST Plain objects 1.76 slim-ast plain objects 1.562 slim-ast shared structs 2.013 slim-ast shared structs across 8 workers 1.082