mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
fix(53011): Illegal declaration file can be emitted (duplicate parameter names) when spreading tuples into parameter positions (#53028)
This commit is contained in:
@@ -12644,11 +12644,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number) {
|
||||
const elementTypes = getTypeArguments(restType);
|
||||
const associatedNames = restType.target.labeledElementDeclarations;
|
||||
const associatedNames = getUniqAssociatedNamesFromTupleType(restType);
|
||||
const restParams = map(elementTypes, (t, i) => {
|
||||
// Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name
|
||||
const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]);
|
||||
const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i, restType);
|
||||
const name = associatedNames && associatedNames[i] ? associatedNames[i] :
|
||||
getParameterNameAtPosition(sig, restIndex + i, restType);
|
||||
const flags = restType.target.elementFlags[i];
|
||||
const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter :
|
||||
flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0;
|
||||
@@ -12658,6 +12658,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
});
|
||||
return concatenate(sig.parameters.slice(0, restIndex), restParams);
|
||||
}
|
||||
|
||||
function getUniqAssociatedNamesFromTupleType(type: TupleTypeReference) {
|
||||
const associatedNamesMap = new Map<__String, number>();
|
||||
return map(type.target.labeledElementDeclarations, labeledElement => {
|
||||
const name = getTupleElementLabel(labeledElement);
|
||||
const prevCounter = associatedNamesMap.get(name);
|
||||
if (prevCounter === undefined) {
|
||||
associatedNamesMap.set(name, 1);
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
associatedNamesMap.set(name, prevCounter + 1);
|
||||
return `${name}_${prevCounter}` as __String;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
|
||||
|
||||
40
tests/baselines/reference/spreadParameterTupleType.js
Normal file
40
tests/baselines/reference/spreadParameterTupleType.js
Normal file
@@ -0,0 +1,40 @@
|
||||
//// [spreadParameterTupleType.ts]
|
||||
function f1() {
|
||||
type A = [s: string];
|
||||
type C = [...A, ...A];
|
||||
|
||||
return function fn(...args: C) { }
|
||||
}
|
||||
|
||||
function f2() {
|
||||
type A = [a: string];
|
||||
type B = [b: string];
|
||||
type C = [c: string];
|
||||
type D = [...A, ...A, ...B, ...A, ...B, ...B, ...A, ...C];
|
||||
|
||||
return function fn(...args: D) { }
|
||||
}
|
||||
|
||||
|
||||
//// [spreadParameterTupleType.js]
|
||||
function f1() {
|
||||
return function fn() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
};
|
||||
}
|
||||
function f2() {
|
||||
return function fn() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//// [spreadParameterTupleType.d.ts]
|
||||
declare function f1(): (s: string, s_1: string) => void;
|
||||
declare function f2(): (a: string, a_1: string, b: string, a_2: string, b_1: string, b_2: string, a_3: string, c: string) => void;
|
||||
47
tests/baselines/reference/spreadParameterTupleType.symbols
Normal file
47
tests/baselines/reference/spreadParameterTupleType.symbols
Normal file
@@ -0,0 +1,47 @@
|
||||
=== tests/cases/compiler/spreadParameterTupleType.ts ===
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(spreadParameterTupleType.ts, 0, 0))
|
||||
|
||||
type A = [s: string];
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 0, 15))
|
||||
|
||||
type C = [...A, ...A];
|
||||
>C : Symbol(C, Decl(spreadParameterTupleType.ts, 1, 25))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 0, 15))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 0, 15))
|
||||
|
||||
return function fn(...args: C) { }
|
||||
>fn : Symbol(fn, Decl(spreadParameterTupleType.ts, 4, 10))
|
||||
>args : Symbol(args, Decl(spreadParameterTupleType.ts, 4, 23))
|
||||
>C : Symbol(C, Decl(spreadParameterTupleType.ts, 1, 25))
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(spreadParameterTupleType.ts, 5, 1))
|
||||
|
||||
type A = [a: string];
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 7, 15))
|
||||
|
||||
type B = [b: string];
|
||||
>B : Symbol(B, Decl(spreadParameterTupleType.ts, 8, 25))
|
||||
|
||||
type C = [c: string];
|
||||
>C : Symbol(C, Decl(spreadParameterTupleType.ts, 9, 25))
|
||||
|
||||
type D = [...A, ...A, ...B, ...A, ...B, ...B, ...A, ...C];
|
||||
>D : Symbol(D, Decl(spreadParameterTupleType.ts, 10, 25))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 7, 15))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 7, 15))
|
||||
>B : Symbol(B, Decl(spreadParameterTupleType.ts, 8, 25))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 7, 15))
|
||||
>B : Symbol(B, Decl(spreadParameterTupleType.ts, 8, 25))
|
||||
>B : Symbol(B, Decl(spreadParameterTupleType.ts, 8, 25))
|
||||
>A : Symbol(A, Decl(spreadParameterTupleType.ts, 7, 15))
|
||||
>C : Symbol(C, Decl(spreadParameterTupleType.ts, 9, 25))
|
||||
|
||||
return function fn(...args: D) { }
|
||||
>fn : Symbol(fn, Decl(spreadParameterTupleType.ts, 13, 10))
|
||||
>args : Symbol(args, Decl(spreadParameterTupleType.ts, 13, 23))
|
||||
>D : Symbol(D, Decl(spreadParameterTupleType.ts, 10, 25))
|
||||
}
|
||||
|
||||
37
tests/baselines/reference/spreadParameterTupleType.types
Normal file
37
tests/baselines/reference/spreadParameterTupleType.types
Normal file
@@ -0,0 +1,37 @@
|
||||
=== tests/cases/compiler/spreadParameterTupleType.ts ===
|
||||
function f1() {
|
||||
>f1 : () => (s: string, s_1: string) => void
|
||||
|
||||
type A = [s: string];
|
||||
>A : [s: string]
|
||||
|
||||
type C = [...A, ...A];
|
||||
>C : [s: string, s: string]
|
||||
|
||||
return function fn(...args: C) { }
|
||||
>function fn(...args: C) { } : (s: string, s_1: string) => void
|
||||
>fn : (s: string, s_1: string) => void
|
||||
>args : [s: string, s: string]
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => (a: string, a_1: string, b: string, a_2: string, b_1: string, b_2: string, a_3: string, c: string) => void
|
||||
|
||||
type A = [a: string];
|
||||
>A : [a: string]
|
||||
|
||||
type B = [b: string];
|
||||
>B : [b: string]
|
||||
|
||||
type C = [c: string];
|
||||
>C : [c: string]
|
||||
|
||||
type D = [...A, ...A, ...B, ...A, ...B, ...B, ...A, ...C];
|
||||
>D : [a: string, a: string, b: string, a: string, b: string, b: string, a: string, c: string]
|
||||
|
||||
return function fn(...args: D) { }
|
||||
>function fn(...args: D) { } : (a: string, a_1: string, b: string, a_2: string, b_1: string, b_2: string, a_3: string, c: string) => void
|
||||
>fn : (a: string, a_1: string, b: string, a_2: string, b_1: string, b_2: string, a_3: string, c: string) => void
|
||||
>args : [a: string, a: string, b: string, a: string, b: string, b: string, a: string, c: string]
|
||||
}
|
||||
|
||||
17
tests/cases/compiler/spreadParameterTupleType.ts
Normal file
17
tests/cases/compiler/spreadParameterTupleType.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @declaration: true
|
||||
|
||||
function f1() {
|
||||
type A = [s: string];
|
||||
type C = [...A, ...A];
|
||||
|
||||
return function fn(...args: C) { }
|
||||
}
|
||||
|
||||
function f2() {
|
||||
type A = [a: string];
|
||||
type B = [b: string];
|
||||
type C = [c: string];
|
||||
type D = [...A, ...A, ...B, ...A, ...B, ...B, ...A, ...C];
|
||||
|
||||
return function fn(...args: D) { }
|
||||
}
|
||||
Reference in New Issue
Block a user