Merge pull request #5459 from Microsoft/partialSignatureMatching
Fix union type partial signature matching
This commit is contained in:
commit
9b4956fa11
|
@ -5606,18 +5606,31 @@ namespace ts {
|
|||
return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
|
||||
}
|
||||
|
||||
function isMatchingSignature(source: Signature, target: Signature, partialMatch: boolean) {
|
||||
// A source signature matches a target signature if the two signatures have the same number of required,
|
||||
// optional, and rest parameters.
|
||||
if (source.parameters.length === target.parameters.length &&
|
||||
source.minArgumentCount === target.minArgumentCount &&
|
||||
source.hasRestParameter === target.hasRestParameter) {
|
||||
return true;
|
||||
}
|
||||
// A source signature partially matches a target signature if the target signature has no fewer required
|
||||
// parameters and no more overall parameters than the source signature (where a signature with a rest
|
||||
// parameter is always considered to have more overall parameters than one without).
|
||||
if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (
|
||||
source.hasRestParameter && !target.hasRestParameter ||
|
||||
source.hasRestParameter === target.hasRestParameter && source.parameters.length >= target.parameters.length)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function compareSignatures(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
|
||||
if (source === target) {
|
||||
return Ternary.True;
|
||||
}
|
||||
if (source.parameters.length !== target.parameters.length ||
|
||||
source.minArgumentCount !== target.minArgumentCount ||
|
||||
source.hasRestParameter !== target.hasRestParameter) {
|
||||
if (!partialMatch ||
|
||||
source.parameters.length < target.parameters.length && !source.hasRestParameter ||
|
||||
source.minArgumentCount > target.minArgumentCount) {
|
||||
return Ternary.False;
|
||||
}
|
||||
if (!(isMatchingSignature(source, target, partialMatch))) {
|
||||
return Ternary.False;
|
||||
}
|
||||
let result = Ternary.True;
|
||||
if (source.typeParameters && target.typeParameters) {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(10,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(20,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(23,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
tests/cases/conformance/types/union/unionTypeCallSignatures4.ts(25,1): error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/union/unionTypeCallSignatures4.ts (4 errors) ====
|
||||
type F1 = (a: string, b?: string) => void;
|
||||
type F2 = (a: string, b?: string, c?: string) => void;
|
||||
type F3 = (a: string, ...rest: string[]) => void;
|
||||
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||
type F5 = (a: string, b: string) => void;
|
||||
|
||||
var f12: F1 | F2;
|
||||
f12("a");
|
||||
f12("a", "b");
|
||||
f12("a", "b", "c"); // error
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
var f34: F3 | F4;
|
||||
f34("a");
|
||||
f34("a", "b");
|
||||
f34("a", "b", "c");
|
||||
|
||||
var f1234: F1 | F2 | F3 | F4;
|
||||
f1234("a");
|
||||
f1234("a", "b");
|
||||
f1234("a", "b", "c"); // error
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
||||
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||
f12345("a"); // error
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
f12345("a", "b");
|
||||
f12345("a", "b", "c"); // error
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2346: Supplied parameters do not match any signature of call target.
|
||||
|
45
tests/baselines/reference/unionTypeCallSignatures4.js
Normal file
45
tests/baselines/reference/unionTypeCallSignatures4.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
//// [unionTypeCallSignatures4.ts]
|
||||
type F1 = (a: string, b?: string) => void;
|
||||
type F2 = (a: string, b?: string, c?: string) => void;
|
||||
type F3 = (a: string, ...rest: string[]) => void;
|
||||
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||
type F5 = (a: string, b: string) => void;
|
||||
|
||||
var f12: F1 | F2;
|
||||
f12("a");
|
||||
f12("a", "b");
|
||||
f12("a", "b", "c"); // error
|
||||
|
||||
var f34: F3 | F4;
|
||||
f34("a");
|
||||
f34("a", "b");
|
||||
f34("a", "b", "c");
|
||||
|
||||
var f1234: F1 | F2 | F3 | F4;
|
||||
f1234("a");
|
||||
f1234("a", "b");
|
||||
f1234("a", "b", "c"); // error
|
||||
|
||||
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||
f12345("a"); // error
|
||||
f12345("a", "b");
|
||||
f12345("a", "b", "c"); // error
|
||||
|
||||
|
||||
//// [unionTypeCallSignatures4.js]
|
||||
var f12;
|
||||
f12("a");
|
||||
f12("a", "b");
|
||||
f12("a", "b", "c"); // error
|
||||
var f34;
|
||||
f34("a");
|
||||
f34("a", "b");
|
||||
f34("a", "b", "c");
|
||||
var f1234;
|
||||
f1234("a");
|
||||
f1234("a", "b");
|
||||
f1234("a", "b", "c"); // error
|
||||
var f12345;
|
||||
f12345("a"); // error
|
||||
f12345("a", "b");
|
||||
f12345("a", "b", "c"); // error
|
|
@ -0,0 +1,25 @@
|
|||
type F1 = (a: string, b?: string) => void;
|
||||
type F2 = (a: string, b?: string, c?: string) => void;
|
||||
type F3 = (a: string, ...rest: string[]) => void;
|
||||
type F4 = (a: string, b?: string, ...rest: string[]) => void;
|
||||
type F5 = (a: string, b: string) => void;
|
||||
|
||||
var f12: F1 | F2;
|
||||
f12("a");
|
||||
f12("a", "b");
|
||||
f12("a", "b", "c"); // error
|
||||
|
||||
var f34: F3 | F4;
|
||||
f34("a");
|
||||
f34("a", "b");
|
||||
f34("a", "b", "c");
|
||||
|
||||
var f1234: F1 | F2 | F3 | F4;
|
||||
f1234("a");
|
||||
f1234("a", "b");
|
||||
f1234("a", "b", "c"); // error
|
||||
|
||||
var f12345: F1 | F2 | F3 | F4 | F5;
|
||||
f12345("a"); // error
|
||||
f12345("a", "b");
|
||||
f12345("a", "b", "c"); // error
|
Loading…
Reference in a new issue