ReviewOS

also looking at this

stacks/dtsx

fix(emit): skip a satisfies type that is cut from inside the initializer

#3123
Open mkantautas wants to merge fix/satisfies-top-level into main
3 files +109 -3
8 days ago

Summary

The text after the last satisfies in an initializer is taken as the declared type, wherever that satisfies stands. Vue's compiler-core has

export const TS_NODE_TYPES: string[] = [
  'TSAsExpression', // foo as number
  'TSTypeAssertion', // (<number>foo)
  'TSNonNullExpression', // foo!
  'TSInstantiationExpression', // foo<string>
  'TSSatisfiesExpression', // foo satisfies T
]

and dtsx emits export declare const TS_NODE_TYPES: T\n];, which does not parse. A satisfies in a string, a nested element or a function body does the same: knip's vue, rsbuild and typescript plugins (satisfies WebpackConfiguration inside an arrow function body) and stacks' resources/data/features.ts (inside a template literal) come out unparsable.

Changes

Text cut from inside the initializer closes a bracket it never opened or leaves a string open (T\n], Y', Item], Cfg; return c },\n}); a type does neither. processVariableDeclaration now uses the extracted text only when a new isBalancedType check says it is well formed. That check scans the text as a type: strings, template literals, comments, and (, [, { closing in order. Otherwise the declaration keeps its annotation (TS_NODE_TYPES: string[]), or unknown, as when no satisfies type is found. A top-level satisfies T still emits T, and extractSatisfiesType is unchanged.

Testing

New test/satisfies-top-level.test.ts. A satisfies in a comment, a string, a nested element, a method body, or a string after a regex must give parseable output without the cut text; on main those 5 cases fail. The test also covers top-level satisfies with function types, template literal types, brackets inside string literal types and comments, regexes, division after !, a nested template literal with a URL and parenthesized JSX, all typed as before, as well as a value ending in an empty satisfies.

bun test (Zig library built with the pinned Zig, so its tests run too), typecheck, lint and zig build test pass. Over 4,192 files from vue-core, vue-router, pinia and knip (LF and CRLF), and 11,776 more from tailwindcss, stacks, eslint-plugin-vue and home, the only outputs that change are the five above. Each now parses with its own annotation.

3 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.