ReviewOS

also looking at this

stacks/dtsx

fix(inference): leave defaults out of annotated destructured arrow parameters

#3127
Open mkantautas wants to merge fix/arrow-destructuring-defaults into main
2 files +248 -2
8 days ago

Summary

An arrow function's destructured parameter keeps its default values:

export const dirGlob = ({ cwd, patterns, gitignore = true }: GlobOptions) => ...

emits ({ cwd, patterns, gitignore = true }: GlobOptions) => ..., and TypeScript rejects an initializer in a declaration (TS2371); knip's util/glob does not parse for this reason. #3093 removed a parameter's own default and #3095 fixed destructured parameters of function declarations; an arrow function const goes through cleanParameterDefaults, which only looked for a default at the top level of a parameter.

Changes

A destructuring pattern with a type annotation now loses its defaults, as tsc writes it: { cwd, patterns, gitignore }: GlobOptions.

  • Reading the pattern. stripPatternDefaults parses the pattern with a small grammar: names, string and number keys, nested patterns and rest elements, with defaults that are each a name, a number, a string, [] or {}.
  • What is left alone. Any other pattern (a default with an operator or a call, a computed key) is left as written. So is a pattern without a type, whose defaults are what give it its type.
  • Lists without their own defaults. When no parameter has a default of its own, only such patterns are rewritten and the rest of the parameter list is kept as written; a list holding a / or a template literal is left alone.

Testing

New test/arrow-destructuring-defaults.test.ts. Each of these is type-checked through a consumer with the existing runTsc helper; main fails these 6 cases:

  • object and array patterns;
  • a nested pattern with its own default;
  • a pattern beside a parameter default;
  • defaults that are names, numbers, strings, [], {} and a member path, with a rest element;
  • two patterns around a generic type.

Fifteen more cases check that patterns it does not handle stay exactly as main writes them: comments, a regex, type arguments, a computed key, comparisons, nested templates, unannotated patterns, a sibling parameter with a comment or a template literal type.

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), the only output that changes is knip's util/glob, which now parses. Over 11,774 more from tailwindcss, stacks, eslint-plugin-vue and home, nothing changes.

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

Sign in to comment on this pull request.