Description
π Search Terms
discrimnated type union node internal source api
β Viability Checklist
- 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, new syntax sugar for JS, etc.)
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
Happy Halloween π! In the spirit of the holiday, I'd like to resurrect #13634: using a discriminated unions for Node
categories. Roughly paraphrasing #18285's very good description here:
As mentioned in #18214 (comment), TypeScript's source can remove a lot of casts by using a discriminated union for Node
.
While this should not affect TypeScript's runtime performance (as it just changes its types, mostly) it may cause TypeScript to take longer to compile itself.
#13634 was declined in 2018 for performance concerns (#13634 (comment)) but I hope that the years of performance improvements since then have since made this possible.
π Motivating Example
Switching TypeScript's Node
from an interface from a discriminated type union would allow .kind
checks to narrow types of values declared as Node
.
import * as ts from "typescript";
declare const node: ts.Node;
if (node.kind === ts.SyntaxKind.FunctionDeclaration) {
node.name?.text;
// ~~~~
// Property 'name' does not exist on type 'Node'.
}
π» Use Cases
In TypeScript itself, a match-case-and-full-word search for /(?:name|node|parent) as \w{5,}/
in src/**/*.ts
excluding *test*
yields 1879 matches right now. After prototyping it locally and enabling @typescript-eslint/no-unnecessary-type-assertion
, I mostly-automatically reduced it to 987 matches. More removals could likely be enacted with manual effort.
- Previous attempt: Use discriminated unions for node categoriesΒ #18285
- My attempt: [Reference] feat: switched Node to a discriminated unionΒ #56274
- (edit) Wes' PR, which everyone else in this thread except Andarist has previous commented on but somehow forgot about: Use union types for all common classes of AST nodesΒ #54148
In community projects that use the TypeScript AST, including typescript-eslint, we'd similarly be able to have more precise type information on TS AST nodes.
#13634 mentions other consumers too, such as Babel's https://github.com/babel/babel/blob/c446ff85c28e117ebf3cd72cd34ef358f1077aa8/packages/babel-types/src/validators/is.ts.