Summary
An arrow function returning a parameter whose type is a function type gets a cut-off return type:
export const run = (g: () => void) => gemits export declare const run: (g: () => void) => ();, which does not parse. Vue's reactivity arrayInstrumentations (ReturnType<(result: any)>) and a knip loader fixture come out unparsable this way, and tailwind's default theme loses the return type of __BARE_VALUE__ ((value: NamedUtilityValue) instead of (value: NamedUtilityValue) => string | undefined).
Changes
To infer a return type from the body, collectParameterTypes reads each parameter's type up to its first =, taken as the start of a default. In () => void that = belongs to the arrow. A new findTypeDefault takes the first = outside the type's brackets and strings that is not part of =>. A type holding a comment or a template literal, or text that is not one whole type (a top-level comma, an unopened bracket or an unclosed string, which the parameter splitter can leave), is read as before.
Testing
New test/function-typed-parameter-return.test.ts. Five cases are type-checked through a consumer with the existing runTsc helper, and main fails all five:
- a function type;
- a function type in an object type with a default;
- beside a defaulted parameter;
- returning a type parameter;
- inside
Array<() => void>with a default.
Eight more cases check that output parses and matches. One is a class method returning a function-typed parameter. The rest are types with comments, quoted delimiters and nested template literals, which must read as before.
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 outputs that change are the Vue and knip files above, which now parse. Over 11,774 more from tailwindcss, stacks, eslint-plugin-vue and home, the only change is tailwind's default theme.