Skip to content

Commit ab2994f

Browse files
committed
Fix union types of variadic functions
The check used `=== len - 1` instead of `>= len - 1` to check whether a parameter index might be pointing to a rest argument.
1 parent 7a10043 commit ab2994f

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5620,11 +5620,10 @@ namespace ts {
56205620
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
56215621
source = getErasedSignature(source);
56225622
target = getErasedSignature(target);
5623-
let sourceLen = source.parameters.length;
56245623
let targetLen = target.parameters.length;
56255624
for (let i = 0; i < targetLen; i++) {
5626-
let s = source.hasRestParameter && i === sourceLen - 1 ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
5627-
let t = target.hasRestParameter && i === targetLen - 1 ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
5625+
let s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
5626+
let t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
56285627
let related = compareTypes(s, t);
56295628
if (!related) {
56305629
return Ternary.False;
@@ -5637,6 +5636,10 @@ namespace ts {
56375636
return result;
56385637
}
56395638

5639+
function isRestParameterIndex(signature: Signature, parameterIndex: number) {
5640+
return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1;
5641+
}
5642+
56405643
function isSupertypeOfEach(candidate: Type, types: Type[]): boolean {
56415644
for (let type of types) {
56425645
if (candidate !== type && !isTypeSubtypeOf(type, candidate)) return false;
@@ -6798,8 +6801,9 @@ namespace ts {
67986801
}
67996802

68006803
// If last parameter is contextually rest parameter get its type
6801-
if (indexOfParameter === (func.parameters.length - 1) &&
6802-
funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) {
6804+
if (funcHasRestParameters &&
6805+
indexOfParameter === (func.parameters.length - 1) &&
6806+
isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
68036807
return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters));
68046808
}
68056809
}
@@ -8390,7 +8394,7 @@ namespace ts {
83908394
// If spread arguments are present, check that they correspond to a rest parameter. If so, no
83918395
// further checking is necessary.
83928396
if (spreadArgIndex >= 0) {
8393-
return signature.hasRestParameter && spreadArgIndex >= signature.parameters.length - 1;
8397+
return isRestParameterIndex(signature, spreadArgIndex);
83948398
}
83958399

83968400
// Too many arguments implies incorrect arity.
@@ -9381,7 +9385,7 @@ namespace ts {
93819385
let contextualParameterType = getTypeAtPosition(context, i);
93829386
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
93839387
}
9384-
if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) {
9388+
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
93859389
let parameter = lastOrUndefined(signature.parameters);
93869390
let contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
93879391
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);

0 commit comments

Comments
 (0)