ReviewOS

stacks/dtsx

Destructured parameter with inline type emits malformed .d.ts

#3095
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Summary

When a function parameter is a destructured object with an inline type annotation and a default value, dtsx emits invalid TypeScript in the .d.ts output. The emitted file fails to parse with error TS1138: Parameter declaration expected.

Minimal repro

// src/index.ts
export function f(
  argv: string[] = [],
  {
    run = true,
    exitOnError = false,
  }: { run?: boolean, exitOnError?: boolean } = {},
): Promise<void> {
  return Promise.resolve()
}

Expected .d.ts

export declare function f(
  argv?: string[],
  options?: { run?: boolean, exitOnError?: boolean },
): Promise<void>;

(or any other valid form — e.g. { run, exitOnError }?: { ... })

Actual .d.ts (broken)

export declare function f(argv?: string[], }: { run?: boolean, exitOnError?: boolean } = {},: unknown): Promise<void>;

Note the ,: unknown): — dtsx appears to emit : unknown as a placeholder for a parameter name it couldn't synthesize for the destructured arg, but keeps the trailing comma + return type, producing a sequence (,: unknown):) that TypeScript can't parse.

Real-world hit

This was the cause of @stacksjs/clapp@0.2.3's broken published dist/CLI.d.ts(72,50) — see stacksjs/clapp@3800823 for the source-side workaround Chris had to apply. Every consumer of @stacksjs/clapp@0.2.3 (transitive or direct) hit error TS1138: Parameter declaration expected. at compile time.

The workaround required rewriting the source signature from:

async parse(
  argv: string[] = processArgs,
  { run = true, exitOnError = false }: { run?: boolean, exitOnError?: boolean } = {},
): Promise<ParsedArgv>

to:

async parse(
  argv: string[] = processArgs,
  options: ParseOptions = {},
): Promise<ParsedArgv> {
  let { run = true, exitOnError = false } = options
  // …
}

The pattern that breaks is well-formed and common in modern TypeScript — would be good to fix at the dtsx layer so consumers don't have to refactor source to dodge it.

Environment

  • dtsx: latest (via bun-plugin-dtsx@0.9.x)
  • bun: 1.3.13

Sign in to comment on this issue.