Skip to content

Commit 17b7c3e

Browse files
committed
Merge pull request microsoft#7226 from Microsoft/bindingPatternsInTypes
Correctly serialize types with signatures containing binding patterns
2 parents 647280b + 87a00c3 commit 17b7c3e

20 files changed

Lines changed: 260 additions & 184 deletions

src/compiler/checker.ts

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,7 +2176,12 @@ namespace ts {
21762176
if (isRestParameter(parameterNode)) {
21772177
writePunctuation(writer, SyntaxKind.DotDotDotToken);
21782178
}
2179-
appendSymbolNameOnly(p, writer);
2179+
if (isBindingPattern(parameterNode.name)) {
2180+
buildBindingPatternDisplay(<BindingPattern>parameterNode.name, writer, enclosingDeclaration, flags, symbolStack);
2181+
}
2182+
else {
2183+
appendSymbolNameOnly(p, writer);
2184+
}
21802185
if (isOptionalParameter(parameterNode)) {
21812186
writePunctuation(writer, SyntaxKind.QuestionToken);
21822187
}
@@ -2186,20 +2191,63 @@ namespace ts {
21862191
buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack);
21872192
}
21882193

2194+
function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
2195+
// We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node.
2196+
if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) {
2197+
writePunctuation(writer, SyntaxKind.OpenBraceToken);
2198+
buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack));
2199+
writePunctuation(writer, SyntaxKind.CloseBraceToken);
2200+
}
2201+
else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) {
2202+
writePunctuation(writer, SyntaxKind.OpenBracketToken);
2203+
const elements = bindingPattern.elements;
2204+
buildDisplayForCommaSeparatedList(elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack));
2205+
if (elements && elements.hasTrailingComma) {
2206+
writePunctuation(writer, SyntaxKind.CommaToken);
2207+
}
2208+
writePunctuation(writer, SyntaxKind.CloseBracketToken);
2209+
}
2210+
}
2211+
2212+
function buildBindingElementDisplay(bindingElement: BindingElement, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
2213+
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
2214+
return;
2215+
}
2216+
Debug.assert(bindingElement.kind === SyntaxKind.BindingElement);
2217+
if (bindingElement.propertyName) {
2218+
writer.writeSymbol(getTextOfNode(bindingElement.propertyName), bindingElement.symbol);
2219+
writePunctuation(writer, SyntaxKind.ColonToken);
2220+
writeSpace(writer);
2221+
}
2222+
if (isBindingPattern(bindingElement.name)) {
2223+
buildBindingPatternDisplay(<BindingPattern>bindingElement.name, writer, enclosingDeclaration, flags, symbolStack);
2224+
}
2225+
else {
2226+
if (bindingElement.dotDotDotToken) {
2227+
writePunctuation(writer, SyntaxKind.DotDotDotToken);
2228+
}
2229+
appendSymbolNameOnly(bindingElement.symbol, writer);
2230+
}
2231+
}
2232+
21892233
function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
21902234
if (typeParameters && typeParameters.length) {
21912235
writePunctuation(writer, SyntaxKind.LessThanToken);
2192-
for (let i = 0; i < typeParameters.length; i++) {
2193-
if (i > 0) {
2194-
writePunctuation(writer, SyntaxKind.CommaToken);
2195-
writeSpace(writer);
2196-
}
2197-
buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, symbolStack);
2198-
}
2236+
buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack));
21992237
writePunctuation(writer, SyntaxKind.GreaterThanToken);
22002238
}
22012239
}
22022240

2241+
function buildDisplayForCommaSeparatedList<T>(list: T[], writer: SymbolWriter, action: (item: T) => void) {
2242+
for (let i = 0; i < list.length; i++) {
2243+
if (i > 0) {
2244+
writePunctuation(writer, SyntaxKind.CommaToken);
2245+
writeSpace(writer);
2246+
}
2247+
action(list[i]);
2248+
}
2249+
}
2250+
22032251
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
22042252
if (typeParameters && typeParameters.length) {
22052253
writePunctuation(writer, SyntaxKind.LessThanToken);

tests/baselines/reference/arrayBindingPatternOmittedExpressions.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var results: string[];
2525

2626

2727
function f([, a, , b, , , , s, , , ] = results) {
28-
>f : ([, a, , b, , , , s, , , ]?: string[]) => void
28+
>f : ([, a, , b, , , , s, , ,]?: string[]) => void
2929
> : undefined
3030
>a : string
3131
> : undefined

tests/baselines/reference/arrowFunctionExpressions.types

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,31 @@ var p4 = ([, ...a]) => { };
7777
>a : any[]
7878

7979
var p5 = ([a = 1]) => { };
80-
>p5 : ([a = 1]: [number]) => void
81-
>([a = 1]) => { } : ([a = 1]: [number]) => void
80+
>p5 : ([a]: [number]) => void
81+
>([a = 1]) => { } : ([a]: [number]) => void
8282
>a : number
8383
>1 : number
8484

8585
var p6 = ({ a }) => { };
86-
>p6 : ({ a }: { a: any; }) => void
87-
>({ a }) => { } : ({ a }: { a: any; }) => void
86+
>p6 : ({a}: { a: any; }) => void
87+
>({ a }) => { } : ({a}: { a: any; }) => void
8888
>a : any
8989

9090
var p7 = ({ a: { b } }) => { };
91-
>p7 : ({ a: { b } }: { a: { b: any; }; }) => void
92-
>({ a: { b } }) => { } : ({ a: { b } }: { a: { b: any; }; }) => void
91+
>p7 : ({a: {b}}: { a: { b: any; }; }) => void
92+
>({ a: { b } }) => { } : ({a: {b}}: { a: { b: any; }; }) => void
9393
>a : any
9494
>b : any
9595

9696
var p8 = ({ a = 1 }) => { };
97-
>p8 : ({ a = 1 }: { a?: number; }) => void
98-
>({ a = 1 }) => { } : ({ a = 1 }: { a?: number; }) => void
97+
>p8 : ({a}: { a?: number; }) => void
98+
>({ a = 1 }) => { } : ({a}: { a?: number; }) => void
9999
>a : number
100100
>1 : number
101101

102102
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
103-
>p9 : ({ a: { b = 1 } = { b: 1 } }: { a?: { b?: number; }; }) => void
104-
>({ a: { b = 1 } = { b: 1 } }) => { } : ({ a: { b = 1 } = { b: 1 } }: { a?: { b?: number; }; }) => void
103+
>p9 : ({a: {b}}: { a?: { b?: number; }; }) => void
104+
>({ a: { b = 1 } = { b: 1 } }) => { } : ({a: {b}}: { a?: { b?: number; }; }) => void
105105
>a : any
106106
>b : number
107107
>1 : number
@@ -110,8 +110,8 @@ var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
110110
>1 : number
111111

112112
var p10 = ([{ value, done }]) => { };
113-
>p10 : ([{ value, done }]: [{ value: any; done: any; }]) => void
114-
>([{ value, done }]) => { } : ([{ value, done }]: [{ value: any; done: any; }]) => void
113+
>p10 : ([{value, done}]: [{ value: any; done: any; }]) => void
114+
>([{ value, done }]) => { } : ([{value, done}]: [{ value: any; done: any; }]) => void
115115
>value : any
116116
>done : any
117117

tests/baselines/reference/declarationEmitDestructuring5.types

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
=== tests/cases/compiler/declarationEmitDestructuring5.ts ===
22
function baz([, z, , ]) { }
3-
>baz : ([, z, , ]: [any, any, any]) => void
3+
>baz : ([, z, ,]: [any, any, any]) => void
44
> : undefined
55
>z : any
66
> : undefined
77

88
function foo([, b, ]: [any, any]): void { }
9-
>foo : ([, b, ]: [any, any]) => void
9+
>foo : ([, b,]: [any, any]) => void
1010
> : undefined
1111
>b : any
1212

1313
function bar([z, , , ]) { }
14-
>bar : ([z, , , ]: [any, any, any]) => void
14+
>bar : ([z, , ,]: [any, any, any]) => void
1515
>z : any
1616
> : undefined
1717
> : undefined
1818

1919
function bar1([z, , , ] = [1, 3, 4, 6, 7]) { }
20-
>bar1 : ([z, , , ]?: [number, number, number, number, number]) => void
20+
>bar1 : ([z, , ,]?: [number, number, number, number, number]) => void
2121
>z : number
2222
> : undefined
2323
> : undefined
@@ -29,7 +29,7 @@ function bar1([z, , , ] = [1, 3, 4, 6, 7]) { }
2929
>7 : number
3030

3131
function bar2([,,z, , , ]) { }
32-
>bar2 : ([,,z, , , ]: [any, any, any, any, any]) => void
32+
>bar2 : ([, , z, , ,]: [any, any, any, any, any]) => void
3333
> : undefined
3434
> : undefined
3535
>z : any

tests/baselines/reference/declarationEmitDestructuringOptionalBindingParametersInOverloads.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function foo(...rest: any[]) {
1212
}
1313

1414
function foo2( { x, y, z }?: { x: string; y: number; z: boolean });
15-
>foo2 : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => any
15+
>foo2 : ({x, y, z}?: { x: string; y: number; z: boolean; }) => any
1616
>x : string
1717
>y : number
1818
>z : boolean
@@ -21,7 +21,7 @@ function foo2( { x, y, z }?: { x: string; y: number; z: boolean });
2121
>z : boolean
2222

2323
function foo2(...rest: any[]) {
24-
>foo2 : ({ x, y, z }?: { x: string; y: number; z: boolean; }) => any
24+
>foo2 : ({x, y, z}?: { x: string; y: number; z: boolean; }) => any
2525
>rest : any[]
2626

2727
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [declarationEmit_bindingPatterns.ts]
2+
3+
const k = ({x: z = 'y'}) => { }
4+
5+
var a;
6+
function f({} = a, [] = a, { p: {} = a} = a) {
7+
}
8+
9+
//// [declarationEmit_bindingPatterns.js]
10+
var k = function (_a) {
11+
var _b = _a.x, z = _b === void 0 ? 'y' : _b;
12+
};
13+
var a;
14+
function f(_a, _b, _c) {
15+
var _a = a;
16+
var _b = a;
17+
var _d = (_c === void 0 ? a : _c).p, _e = _d === void 0 ? a : _d;
18+
}
19+
20+
21+
//// [declarationEmit_bindingPatterns.d.ts]
22+
declare const k: ({x: z}: {
23+
x?: string;
24+
}) => void;
25+
declare var a: any;
26+
declare function f({}?: any, []?: any, {p: {}}?: any): void;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/declarationEmit_bindingPatterns.ts ===
2+
3+
const k = ({x: z = 'y'}) => { }
4+
>k : Symbol(k, Decl(declarationEmit_bindingPatterns.ts, 1, 5))
5+
>x : Symbol(x)
6+
>z : Symbol(z, Decl(declarationEmit_bindingPatterns.ts, 1, 12))
7+
8+
var a;
9+
>a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3))
10+
11+
function f({} = a, [] = a, { p: {} = a} = a) {
12+
>f : Symbol(f, Decl(declarationEmit_bindingPatterns.ts, 3, 6))
13+
>a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3))
14+
>a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3))
15+
>a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3))
16+
>a : Symbol(a, Decl(declarationEmit_bindingPatterns.ts, 3, 3))
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/declarationEmit_bindingPatterns.ts ===
2+
3+
const k = ({x: z = 'y'}) => { }
4+
>k : ({x: z}: { x?: string; }) => void
5+
>({x: z = 'y'}) => { } : ({x: z}: { x?: string; }) => void
6+
>x : any
7+
>z : string
8+
>'y' : string
9+
10+
var a;
11+
>a : any
12+
13+
function f({} = a, [] = a, { p: {} = a} = a) {
14+
>f : ({}?: any, []?: any, {p: {}}?: any) => void
15+
>a : any
16+
>a : any
17+
>p : any
18+
>a : any
19+
>a : any
20+
}

tests/baselines/reference/destructuringInFunctionType.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type T2 = ({ a });
2929
>a : any
3030

3131
type F2 = ({ a }) => void;
32-
>F2 : ({ a }: { a: any; }) => void
32+
>F2 : ({a}: { a: any; }) => void
3333
>a : any
3434

3535
type T3 = ([{ a: b }, { b: a }]);
@@ -40,7 +40,7 @@ type T3 = ([{ a: b }, { b: a }]);
4040
>a : a
4141

4242
type F3 = ([{ a: b }, { b: a }]) => void;
43-
>F3 : ([{ a: b }, { b: a }]: [{ a: any; }, { b: any; }]) => void
43+
>F3 : ([{a: b}, {b: a}]: [{ a: any; }, { b: any; }]) => void
4444
>a : any
4545
>b : any
4646
>b : any
@@ -53,13 +53,13 @@ type T4 = ([{ a: [b, c] }]);
5353
>c : c
5454

5555
type F4 = ([{ a: [b, c] }]) => void;
56-
>F4 : ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
56+
>F4 : ([{a: [b, c]}]: [{ a: [any, any]; }]) => void
5757
>a : any
5858
>b : any
5959
>c : any
6060

6161
type C1 = new ([{ a: [b, c] }]) => void;
62-
>C1 : new ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
62+
>C1 : new ([{a: [b, c]}]: [{ a: [any, any]; }]) => void
6363
>a : any
6464
>b : any
6565
>c : any

0 commit comments

Comments
 (0)