Correctly emit bidning pattern with initializer and rest
This commit is contained in:
parent
b5065f1f3a
commit
5979dacf4f
10 changed files with 237 additions and 25 deletions
|
@ -1291,8 +1291,10 @@ module ts {
|
||||||
write("...");
|
write("...");
|
||||||
}
|
}
|
||||||
if (isBindingPattern(node.name)) {
|
if (isBindingPattern(node.name)) {
|
||||||
// By emitting binding pattern as binding pattern in function parameters, language service can provide better signature help
|
// For bindingPattern, we can't simply writeTextOfNode from the source file
|
||||||
write(getTextOfNode(node.name));
|
// because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
|
||||||
|
// Therefore, we will have to recursively emit each element in the bindingPattern.
|
||||||
|
emitBindingPattern(<BindingPattern>node.name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writeTextOfNode(currentSourceFile, node.name);
|
writeTextOfNode(currentSourceFile, node.name);
|
||||||
|
@ -1312,41 +1314,46 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
let diagnosticMessage: DiagnosticMessage;
|
let diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
|
return diagnosticMessage !== undefined ? {
|
||||||
|
diagnosticMessage,
|
||||||
|
errorNode: node,
|
||||||
|
typeName: node.name
|
||||||
|
} : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult: SymbolAccessiblityResult) {
|
||||||
switch (node.parent.kind) {
|
switch (node.parent.kind) {
|
||||||
case SyntaxKind.Constructor:
|
case SyntaxKind.Constructor:
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
|
||||||
break;
|
|
||||||
|
|
||||||
case SyntaxKind.ConstructSignature:
|
case SyntaxKind.ConstructSignature:
|
||||||
// Interfaces cannot have parameter types that cannot be named
|
// Interfaces cannot have parameter types that cannot be named
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||||
break;
|
|
||||||
|
|
||||||
case SyntaxKind.CallSignature:
|
case SyntaxKind.CallSignature:
|
||||||
// Interfaces cannot have parameter types that cannot be named
|
// Interfaces cannot have parameter types that cannot be named
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||||
break;
|
|
||||||
|
|
||||||
case SyntaxKind.MethodDeclaration:
|
case SyntaxKind.MethodDeclaration:
|
||||||
case SyntaxKind.MethodSignature:
|
case SyntaxKind.MethodSignature:
|
||||||
if (node.parent.flags & NodeFlags.Static) {
|
if (node.parent.flags & NodeFlags.Static) {
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
|
||||||
}
|
}
|
||||||
else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||||
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||||
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||||
|
@ -1354,30 +1361,80 @@ module ts {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Interfaces cannot have parameter types that cannot be named
|
// Interfaces cannot have parameter types that cannot be named
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case SyntaxKind.FunctionDeclaration:
|
case SyntaxKind.FunctionDeclaration:
|
||||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
return symbolAccesibilityResult.errorModuleName ?
|
||||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
|
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
|
||||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
|
Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
diagnosticMessage,
|
|
||||||
errorNode: node,
|
|
||||||
typeName: node.name
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitBindingPattern(bindingPattern: BindingPattern) {
|
||||||
|
// We have to explicitly emit square bracket and bracket because these tokens are not store inside the node.
|
||||||
|
if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) {
|
||||||
|
write("{");
|
||||||
|
emitCommaList(bindingPattern.elements, emitBindingElement);
|
||||||
|
write("}");
|
||||||
|
}
|
||||||
|
else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) {
|
||||||
|
write("[");
|
||||||
|
emitCommaList(bindingPattern.elements, emitBindingElement);
|
||||||
|
write("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitBindingElement(bindingElement: BindingElement) {
|
||||||
|
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||||
|
let diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||||
|
return diagnosticMessage !== undefined ? {
|
||||||
|
diagnosticMessage,
|
||||||
|
errorNode: bindingElement,
|
||||||
|
typeName: bindingElement.name
|
||||||
|
} : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindingElement.propertyName) {
|
||||||
|
// bindingElement has propertyName property in the following case:
|
||||||
|
// { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y"
|
||||||
|
// We have to explicitly emit the propertyName before descending into its binding elements.
|
||||||
|
// Example:
|
||||||
|
// original: function foo({y: [a,b,c]}) {}
|
||||||
|
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
|
||||||
|
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
|
||||||
|
write(": ");
|
||||||
|
|
||||||
|
// If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
|
||||||
|
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||||
|
}
|
||||||
|
else if (bindingElement.name) {
|
||||||
|
if (isBindingPattern(bindingElement.name)) {
|
||||||
|
// If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
|
||||||
|
// In the case of rest element, we will omit rest element.
|
||||||
|
// Example:
|
||||||
|
// original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {}
|
||||||
|
// emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
|
||||||
|
// original with rest: function foo([a ...c]) {}
|
||||||
|
// emit : declare function foo([a, c]): void;
|
||||||
|
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If the node is just an identifier, we will simply emit the text associated with the node's name
|
||||||
|
// Example:
|
||||||
|
// original: function foo({y = 10, x}) {}
|
||||||
|
// emit : declare function foo({y, x}: {number, any}): void;
|
||||||
|
writeTextOfNode(currentSourceFile, bindingElement.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitNode(node: Node) {
|
function emitNode(node: Node) {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
//// [declarationEmitDestructuringArrayPattern6.ts]
|
||||||
|
function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { }
|
||||||
|
function g([a, b, c, d] = [1, 2, 3, 4]) { }
|
||||||
|
function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ }
|
||||||
|
function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ }
|
||||||
|
|
||||||
|
//// [declarationEmitDestructuringArrayPattern6.js]
|
||||||
|
function f(_a) {
|
||||||
|
var _b = _a === void 0 ? {
|
||||||
|
x: 10,
|
||||||
|
y: [
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
6,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
} : _a, _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, _e = _d === void 0 ? [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
] : _d, a = _e[0], b = _e[1], c = _e[2], d = _e[3];
|
||||||
|
}
|
||||||
|
function g(_a) {
|
||||||
|
var _b = _a === void 0 ? [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
] : _a, a = _b[0], b = _b[1], c = _b[2], d = _b[3];
|
||||||
|
}
|
||||||
|
function h(_a) {
|
||||||
|
var a = _a[0], b = _a[1][0], c = _a[2][0][0], _b = _a[3], _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, a = _d[0], b = _d[1], c = _d[2], _e = _b.z, a1 = _e.a1, b1 = _e.b1;
|
||||||
|
}
|
||||||
|
function h1(_a) {
|
||||||
|
var a = _a[0], b = _a[1][0], c = _a[2][0][0], _b = _a[3], _c = _b.x, x = _c === void 0 ? 10 : _c, _d = _b.y, y = _d === void 0 ? [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
] : _d, _e = _b.z, a1 = _e.a1, b1 = _e.b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [declarationEmitDestructuringArrayPattern6.d.ts]
|
||||||
|
declare function f({x, y: [a, b, c, d]}?: {
|
||||||
|
x: number;
|
||||||
|
y: [number, number, number, number];
|
||||||
|
}): void;
|
||||||
|
declare function g([a, b, c, d]?: [number, number, number, number]): void;
|
||||||
|
declare function h([a, [b], [[c]], {x, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], {
|
||||||
|
x?: number;
|
||||||
|
y: [any, any, any];
|
||||||
|
z: {
|
||||||
|
a1: any;
|
||||||
|
b1: any;
|
||||||
|
};
|
||||||
|
}]): void;
|
||||||
|
declare function h1([a, [b], [[c]], {x, y, z: {a1, b1}}]: [any, [any], [[any]], {
|
||||||
|
x?: number;
|
||||||
|
y?: number[];
|
||||||
|
z: {
|
||||||
|
a1: any;
|
||||||
|
b1: any;
|
||||||
|
};
|
||||||
|
}]): void;
|
|
@ -0,0 +1,49 @@
|
||||||
|
=== tests/cases/compiler/declarationEmitDestructuringArrayPattern6.ts ===
|
||||||
|
function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { }
|
||||||
|
>f : ({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]}?: { x: number; y: [number, number, number, number]; }) => void
|
||||||
|
>x : number
|
||||||
|
>y : unknown
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
>c : number
|
||||||
|
>d : number
|
||||||
|
>[1, 2, 3, 4] : [number, number, number, number]
|
||||||
|
>{ x: 10, y: [2, 4, 6, 8] } : { x: number; y: [number, number, number, number]; }
|
||||||
|
>x : number
|
||||||
|
>y : [number, number, number, number]
|
||||||
|
>[2, 4, 6, 8] : [number, number, number, number]
|
||||||
|
|
||||||
|
function g([a, b, c, d] = [1, 2, 3, 4]) { }
|
||||||
|
>g : ([a, b, c, d]?: [number, number, number, number]) => void
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
>c : number
|
||||||
|
>d : number
|
||||||
|
>[1, 2, 3, 4] : [number, number, number, number]
|
||||||
|
|
||||||
|
function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ }
|
||||||
|
>h : ([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], { x?: number; y: [any, any, any]; z: { a1: any; b1: any; }; }]) => void
|
||||||
|
>a : any
|
||||||
|
>b : any
|
||||||
|
>c : any
|
||||||
|
>x : number
|
||||||
|
>y : unknown
|
||||||
|
>a : any
|
||||||
|
>b : any
|
||||||
|
>c : any
|
||||||
|
>z : unknown
|
||||||
|
>a1 : any
|
||||||
|
>b1 : any
|
||||||
|
|
||||||
|
function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ }
|
||||||
|
>h1 : ([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]: [any, [any], [[any]], { x?: number; y?: number[]; z: { a1: any; b1: any; }; }]) => void
|
||||||
|
>a : any
|
||||||
|
>b : any
|
||||||
|
>c : any
|
||||||
|
>x : number
|
||||||
|
>y : number[]
|
||||||
|
>[1, 2, 3] : number[]
|
||||||
|
>z : unknown
|
||||||
|
>a1 : any
|
||||||
|
>b1 : any
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
//// [declarationEmitDestructuringArrayPattern7.ts]
|
||||||
|
function bar([x, z, ...w]) { }
|
||||||
|
function foo([x, ...y] = [1, "string", true]) { }
|
||||||
|
|
||||||
|
//// [declarationEmitDestructuringArrayPattern7.js]
|
||||||
|
function bar(_a) {
|
||||||
|
var x = _a[0], z = _a[1], w = _a.slice(2);
|
||||||
|
}
|
||||||
|
function foo(_a) {
|
||||||
|
var _b = _a === void 0 ? [
|
||||||
|
1,
|
||||||
|
"string",
|
||||||
|
true
|
||||||
|
] : _a, x = _b[0], y = _b.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [declarationEmitDestructuringArrayPattern7.d.ts]
|
||||||
|
declare function bar([x, z, w]: any[]): void;
|
||||||
|
declare function foo([x, y]?: (string | number | boolean)[]): void;
|
|
@ -0,0 +1,13 @@
|
||||||
|
=== tests/cases/compiler/declarationEmitDestructuringArrayPattern7.ts ===
|
||||||
|
function bar([x, z, ...w]) { }
|
||||||
|
>bar : ([x, z, ...w]: any[]) => void
|
||||||
|
>x : any
|
||||||
|
>z : any
|
||||||
|
>w : any[]
|
||||||
|
|
||||||
|
function foo([x, ...y] = [1, "string", true]) { }
|
||||||
|
>foo : ([x, ...y]?: (string | number | boolean)[]) => void
|
||||||
|
>x : string | number | boolean
|
||||||
|
>y : (string | number | boolean)[]
|
||||||
|
>[1, "string", true] : (string | number | boolean)[]
|
||||||
|
|
|
@ -26,7 +26,7 @@ function foo2() {
|
||||||
|
|
||||||
//// [declarationEmitDestructuringOptionalBindingParametersInOverloads.d.ts]
|
//// [declarationEmitDestructuringOptionalBindingParametersInOverloads.d.ts]
|
||||||
declare function foo([x, y, z]?: [string, number, boolean]): any;
|
declare function foo([x, y, z]?: [string, number, boolean]): any;
|
||||||
declare function foo2({ x, y, z }?: {
|
declare function foo2({x, y, z}?: {
|
||||||
x: string;
|
x: string;
|
||||||
y: number;
|
y: number;
|
||||||
z: boolean;
|
z: boolean;
|
||||||
|
|
|
@ -57,5 +57,5 @@ declare type ObjType1 = {
|
||||||
};
|
};
|
||||||
declare class C3 {
|
declare class C3 {
|
||||||
x: number, y: string, z: boolean;
|
x: number, y: string, z: boolean;
|
||||||
constructor({ x, y, z }: ObjType1);
|
constructor({x, y, z}: ObjType1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ function foo1(_a) {
|
||||||
|
|
||||||
|
|
||||||
//// [declarationEmitDestructuringWithOptionalBindingParameters.d.ts]
|
//// [declarationEmitDestructuringWithOptionalBindingParameters.d.ts]
|
||||||
declare function foo([x,y,z]?: [string, number, boolean]): void;
|
declare function foo([x, y, z]?: [string, number, boolean]): void;
|
||||||
declare function foo1({ x, y, z }?: {
|
declare function foo1({x, y, z}?: {
|
||||||
x: string;
|
x: string;
|
||||||
y: number;
|
y: number;
|
||||||
z: boolean;
|
z: boolean;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// @declaration: true
|
||||||
|
function f({x = 10, y: [a, b, c, d] = [1, 2, 3, 4]} = { x: 10, y: [2, 4, 6, 8] }) { }
|
||||||
|
function g([a, b, c, d] = [1, 2, 3, 4]) { }
|
||||||
|
function h([a, [b], [[c]], {x = 10, y: [a, b, c], z: {a1, b1}}]){ }
|
||||||
|
function h1([a, [b], [[c]], {x = 10, y = [1, 2, 3], z: {a1, b1}}]){ }
|
|
@ -0,0 +1,3 @@
|
||||||
|
// @declaration: true
|
||||||
|
function bar([x, z, ...w]) { }
|
||||||
|
function foo([x, ...y] = [1, "string", true]) { }
|
Loading…
Reference in a new issue