Skip to content

Commit cce2b93

Browse files
committed
Merge branch 'master' into report-multiple-overload-errors
2 parents 34c4047 + b46c44d commit cce2b93

26 files changed

+819
-59
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7234,8 +7234,8 @@ namespace ts {
72347234
function resolveIntersectionTypeMembers(type: IntersectionType) {
72357235
// The members and properties collections are empty for intersection types. To get all properties of an
72367236
// intersection type use getPropertiesOfType (only the language service uses this).
7237-
let callSignatures: ReadonlyArray<Signature> = emptyArray;
7238-
let constructSignatures: ReadonlyArray<Signature> = emptyArray;
7237+
let callSignatures: Signature[] | undefined;
7238+
let constructSignatures: Signature[] | undefined;
72397239
let stringIndexInfo: IndexInfo | undefined;
72407240
let numberIndexInfo: IndexInfo | undefined;
72417241
const types = type.types;
@@ -7257,13 +7257,22 @@ namespace ts {
72577257
return clone;
72587258
});
72597259
}
7260-
constructSignatures = concatenate(constructSignatures, signatures);
7260+
constructSignatures = appendSignatures(constructSignatures, signatures);
72617261
}
7262-
callSignatures = concatenate(callSignatures, getSignaturesOfType(t, SignatureKind.Call));
7262+
callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, SignatureKind.Call));
72637263
stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String));
72647264
numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number));
72657265
}
7266-
setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
7266+
setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, stringIndexInfo, numberIndexInfo);
7267+
}
7268+
7269+
function appendSignatures(signatures: Signature[] | undefined, newSignatures: readonly Signature[]) {
7270+
for (const sig of newSignatures) {
7271+
if (!signatures || every(signatures, s => !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical))) {
7272+
signatures = append(signatures, sig);
7273+
}
7274+
}
7275+
return signatures;
72677276
}
72687277

72697278
/**
@@ -14403,20 +14412,25 @@ namespace ts {
1440314412
if (!(isMatchingSignature(source, target, partialMatch))) {
1440414413
return Ternary.False;
1440514414
}
14406-
// Check that the two signatures have the same number of type parameters. We might consider
14407-
// also checking that any type parameter constraints match, but that would require instantiating
14408-
// the constraints with a common set of type arguments to get relatable entities in places where
14409-
// type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
14410-
// particularly as we're comparing erased versions of the signatures below.
14415+
// Check that the two signatures have the same number of type parameters.
1441114416
if (length(source.typeParameters) !== length(target.typeParameters)) {
1441214417
return Ternary.False;
1441314418
}
14414-
// Spec 1.0 Section 3.8.3 & 3.8.4:
14415-
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
14416-
source = getErasedSignature(source);
14417-
target = getErasedSignature(target);
14419+
// Check that type parameter constraints and defaults match. If they do, instantiate the source
14420+
// signature with the type parameters of the target signature and continue the comparison.
14421+
if (target.typeParameters) {
14422+
const mapper = createTypeMapper(source.typeParameters!, target.typeParameters);
14423+
for (let i = 0; i < target.typeParameters.length; i++) {
14424+
const s = source.typeParameters![i];
14425+
const t = target.typeParameters[i];
14426+
if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) &&
14427+
compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) {
14428+
return Ternary.False;
14429+
}
14430+
}
14431+
source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true);
14432+
}
1441814433
let result = Ternary.True;
14419-
1442014434
if (!ignoreThisTypes) {
1442114435
const sourceThisType = getThisTypeOfSignature(source);
1442214436
if (sourceThisType) {
@@ -14430,7 +14444,6 @@ namespace ts {
1443014444
}
1443114445
}
1443214446
}
14433-
1443414447
const targetLen = getParameterCount(target);
1443514448
for (let i = 0; i < targetLen; i++) {
1443614449
const s = getTypeAtPosition(source, i);

src/compiler/commandLineParser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ namespace ts {
245245
esnext: ModuleKind.ESNext
246246
}),
247247
affectsModuleResolution: true,
248+
affectsEmit: true,
248249
paramType: Diagnostics.KIND,
249250
showInSimplifiedHelpView: true,
250251
category: Diagnostics.Basic_Options,
@@ -590,6 +591,7 @@ namespace ts {
590591
name: "esModuleInterop",
591592
type: "boolean",
592593
affectsSemanticDiagnostics: true,
594+
affectsEmit: true,
593595
showInSimplifiedHelpView: true,
594596
category: Diagnostics.Module_Resolution_Options,
595597
description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports

src/compiler/utilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,13 +2201,13 @@ namespace ts {
22012201
let result: (JSDoc | JSDocTag)[] | undefined;
22022202
// Pull parameter comments from declaring function as well
22032203
if (isVariableLike(hostNode) && hasInitializer(hostNode) && hasJSDocNodes(hostNode.initializer!)) {
2204-
result = addRange(result, (hostNode.initializer as HasJSDoc).jsDoc!);
2204+
result = append(result, last((hostNode.initializer as HasJSDoc).jsDoc!));
22052205
}
22062206

22072207
let node: Node | undefined = hostNode;
22082208
while (node && node.parent) {
22092209
if (hasJSDocNodes(node)) {
2210-
result = addRange(result, node.jsDoc!);
2210+
result = append(result, last(node.jsDoc!));
22112211
}
22122212

22132213
if (node.kind === SyntaxKind.Parameter) {

src/compiler/watch.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,6 @@ namespace ts {
608608
/*@internal*/
609609
getCurrentProgram(): T;
610610
/** Closes the watch */
611-
/*@internal*/
612611
close(): void;
613612
}
614613

src/testRunner/unittests/tsbuild/sample.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ class someClass { }`),
906906
"target": "esnext",
907907
}
908908
}`);
909-
},
909+
},
910910
expectedDiagnostics: [
911911
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
912912
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
@@ -931,6 +931,94 @@ class someClass { }`),
931931
baselineOnly: true,
932932
verifyDiagnostics: true
933933
});
934+
935+
verifyTsbuildOutput({
936+
scenario: "when module option changes",
937+
projFs: () => projFs,
938+
time,
939+
tick,
940+
proj: "sample1",
941+
rootNames: ["/src/core"],
942+
expectedMapFileNames: emptyArray,
943+
lastProjectOutputJs: "/src/core/index.js",
944+
initialBuild: {
945+
modifyFs: fs => fs.writeFileSync("/src/core/tsconfig.json", `{
946+
"compilerOptions": {
947+
"incremental": true,
948+
"module": "commonjs"
949+
}
950+
}`),
951+
expectedDiagnostics: [
952+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
953+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
954+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
955+
]
956+
},
957+
incrementalDtsChangedBuild: {
958+
modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"module": "commonjs"`, `"module": "amd"`),
959+
expectedDiagnostics: [
960+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
961+
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/core/tsconfig.json", "src/core/anotherModule.js", "src/core/tsconfig.json"],
962+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"]
963+
]
964+
},
965+
outputFiles: [
966+
"/src/core/anotherModule.js",
967+
"/src/core/index.js",
968+
"/src/core/tsconfig.tsbuildinfo",
969+
],
970+
baselineOnly: true,
971+
verifyDiagnostics: true
972+
});
973+
974+
verifyTsbuildOutput({
975+
scenario: "when esModuleInterop option changes",
976+
projFs: () => projFs,
977+
time,
978+
tick,
979+
proj: "sample1",
980+
rootNames: ["/src/tests"],
981+
expectedMapFileNames: emptyArray,
982+
lastProjectOutputJs: "/src/tests/index.js",
983+
initialBuild: {
984+
modifyFs: fs => fs.writeFileSync("/src/tests/tsconfig.json", `{
985+
"references": [
986+
{ "path": "../core" },
987+
{ "path": "../logic" }
988+
],
989+
"files": ["index.ts"],
990+
"compilerOptions": {
991+
"composite": true,
992+
"declaration": true,
993+
"forceConsistentCasingInFileNames": true,
994+
"skipDefaultLibCheck": true,
995+
"esModuleInterop": false
996+
}
997+
}`),
998+
expectedDiagnostics: [
999+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
1000+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
1001+
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
1002+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"],
1003+
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
1004+
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"],
1005+
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
1006+
]
1007+
},
1008+
incrementalDtsChangedBuild: {
1009+
modifyFs: fs => replaceText(fs, "/src/tests/tsconfig.json", `"esModuleInterop": false`, `"esModuleInterop": true`),
1010+
expectedDiagnostics: [
1011+
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
1012+
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"],
1013+
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
1014+
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/tsconfig.json"],
1015+
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
1016+
]
1017+
},
1018+
outputFiles: [],
1019+
baselineOnly: true,
1020+
verifyDiagnostics: true
1021+
});
9341022
});
9351023
});
9361024
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4553,6 +4553,8 @@ declare namespace ts {
45534553
interface Watch<T> {
45544554
/** Synchronize with host and get updated program */
45554555
getProgram(): T;
4556+
/** Closes the watch */
4557+
close(): void;
45564558
}
45574559
/**
45584560
* Creates the watch what generates program using the config file

tests/baselines/reference/api/typescript.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4553,6 +4553,8 @@ declare namespace ts {
45534553
interface Watch<T> {
45544554
/** Synchronize with host and get updated program */
45554555
getProgram(): T;
4556+
/** Closes the watch */
4557+
close(): void;
45564558
}
45574559
/**
45584560
* Creates the watch what generates program using the config file
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
tests/cases/compiler/genericSignatureIdentity.ts(10,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T extends number>(x: T) => T'.
2+
tests/cases/compiler/genericSignatureIdentity.ts(14,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T>(x: T) => T'.
3+
tests/cases/compiler/genericSignatureIdentity.ts(18,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T>(x: any) => any'.
4+
5+
6+
==== tests/cases/compiler/genericSignatureIdentity.ts (3 errors) ====
7+
// This test is here to remind us of our current limits of type identity checking.
8+
// Ideally all of the below declarations would be considered different (and thus errors)
9+
// but they aren't because we erase type parameters to type any and don't check that
10+
// constraints are identical.
11+
12+
var x: {
13+
<T extends Date>(x: T): T;
14+
};
15+
16+
var x: {
17+
~
18+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T extends number>(x: T) => T'.
19+
!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here.
20+
<T extends number>(x: T): T;
21+
};
22+
23+
var x: {
24+
~
25+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T>(x: T) => T'.
26+
!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here.
27+
<T>(x: T): T;
28+
};
29+
30+
var x: {
31+
~
32+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '<T extends Date>(x: T) => T', but here has type '<T>(x: any) => any'.
33+
!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here.
34+
<T>(x: any): any;
35+
};
36+

tests/baselines/reference/identityForSignaturesWithTypeParametersAndAny.errors.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(2,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: any, y: any) => any'.
12
tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(5,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'g' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T>(x: any, y: any) => any'.
23
tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(8,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'h' must be of type '<T, U>(x: T, y: U) => T', but here has type '(x: any, y: any) => any'.
34
tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'i' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: any, y: string) => any'.
45
tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(14,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'j' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: any, y: any) => string'.
56

67

7-
==== tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts (4 errors) ====
8+
==== tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts (5 errors) ====
89
var f: <T, U>(x: T, y: U) => T;
910
var f: <T, U>(x: any, y: any) => any;
11+
~
12+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: any, y: any) => any'.
13+
!!! related TS6203 tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts:1:5: 'f' was also declared here.
1014

1115
var g: <T, U>(x: T, y: U) => T;
1216
var g: <T>(x: any, y: any) => any;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts(2,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: U, y: T) => U'.
2+
3+
4+
==== tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts (1 errors) ====
5+
var f: <T, U>(x: T, y: U) => T;
6+
var f: <T, U>(x: U, y: T) => U;
7+
~
8+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '<T, U>(x: T, y: U) => T', but here has type '<T, U>(x: U, y: T) => U'.
9+
!!! related TS6203 tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts:1:5: 'f' was also declared here.

0 commit comments

Comments
 (0)