diff --git a/src/parser/plugins/typescript.ts b/src/parser/plugins/typescript.ts index 604258b9..b7e5d89d 100644 --- a/src/parser/plugins/typescript.ts +++ b/src/parser/plugins/typescript.ts @@ -548,6 +548,21 @@ function tsSkipParameterStart(): boolean { next(); return true; } + // If this is a possible array/object destructure, walk to the matching bracket/brace. + // The next token after will tell us definitively whether this is a function param. + if (match(tt.braceL) || match(tt.bracketL)) { + let depth = 1; + next(); + while (depth > 0) { + if (match(tt.braceL) || match(tt.bracketL)) { + depth++; + } else if (match(tt.braceR) || match(tt.bracketR)) { + depth--; + } + next(); + } + return true; + } return false; } diff --git a/test/typescript-test.ts b/test/typescript-test.ts index b12802d7..ad3d4aa9 100644 --- a/test/typescript-test.ts +++ b/test/typescript-test.ts @@ -1011,4 +1011,21 @@ describe("typescript transform", () => { `, ); }); + + it("allows destructured params in function types", () => { + assertTypeScriptResult( + ` + const f: ({a}: {a: number}) => void = () => {}; + const g: ([a]: Array) => void = () => {}; + const h: ({a: {b: [c]}}: any) => void = () => {}; + const o: ({a: {b: c}}) = {}; + `, + `"use strict"; + const f = () => {}; + const g = () => {}; + const h = () => {}; + const o = {}; + `, + ); + }); });