Skip to content

Commit f2d6eda

Browse files
Merge pull request #38049 from JoshuaKGoldberg/literal-to-primitive-relation-reporting
Report primitive type in literal-to-primitive relation complaints
2 parents 6214bd2 + d3d282c commit f2d6eda

File tree

240 files changed

+1079
-1065
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

240 files changed

+1079
-1065
lines changed

src/compiler/checker.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4139,12 +4139,16 @@ namespace ts {
41394139
let leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left);
41404140
let rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right);
41414141
if (leftStr === rightStr) {
4142-
leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4143-
rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4142+
leftStr = getTypeNameForErrorDisplay(left);
4143+
rightStr = getTypeNameForErrorDisplay(right);
41444144
}
41454145
return [leftStr, rightStr];
41464146
}
41474147

4148+
function getTypeNameForErrorDisplay(type: Type) {
4149+
return typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4150+
}
4151+
41484152
function symbolValueDeclarationIsContextSensitive(symbol: Symbol): boolean {
41494153
return symbol && symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration);
41504154
}
@@ -15726,23 +15730,30 @@ namespace ts {
1572615730
function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) {
1572715731
if (incompatibleStack.length) reportIncompatibleStack();
1572815732
const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target);
15733+
let generalizedSource = source;
15734+
let generalizedSourceType = sourceType;
15735+
15736+
if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) {
15737+
generalizedSource = getBaseTypeOfLiteralType(source);
15738+
generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource);
15739+
}
1572915740

1573015741
if (target.flags & TypeFlags.TypeParameter) {
1573115742
const constraint = getBaseConstraintOfType(target);
15732-
const constraintElab = constraint && isTypeAssignableTo(source, constraint);
15733-
if (constraintElab) {
15743+
let needsOriginalSource;
15744+
if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) {
1573415745
reportError(
1573515746
Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2,
15736-
sourceType,
15747+
needsOriginalSource ? sourceType : generalizedSourceType,
1573715748
targetType,
15738-
typeToString(constraint!),
15749+
typeToString(constraint),
1573915750
);
1574015751
}
1574115752
else {
1574215753
reportError(
1574315754
Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1,
1574415755
targetType,
15745-
sourceType
15756+
generalizedSourceType
1574615757
);
1574715758
}
1574815759
}
@@ -15759,7 +15770,7 @@ namespace ts {
1575915770
}
1576015771
}
1576115772

15762-
reportError(message, sourceType, targetType);
15773+
reportError(message, generalizedSourceType, targetType);
1576315774
}
1576415775

1576515776
function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) {
@@ -17357,6 +17368,21 @@ namespace ts {
1735717368
}
1735817369
}
1735917370

17371+
function typeCouldHaveTopLevelSingletonTypes(type: Type): boolean {
17372+
if (type.flags & TypeFlags.UnionOrIntersection) {
17373+
return !!forEach((type as IntersectionType).types, typeCouldHaveTopLevelSingletonTypes);
17374+
}
17375+
17376+
if (type.flags & TypeFlags.Instantiable) {
17377+
const constraint = getConstraintOfType(type);
17378+
if (constraint) {
17379+
return typeCouldHaveTopLevelSingletonTypes(constraint);
17380+
}
17381+
}
17382+
17383+
return isUnitType(type);
17384+
}
17385+
1736017386
function getBestMatchingType(source: Type, target: UnionOrIntersectionType, isRelatedTo = compareTypesAssignable) {
1736117387
return findMatchingDiscriminantType(source, target, isRelatedTo, /*skipPartial*/ true) ||
1736217388
findMatchingTypeReferenceOrTypeAliasReference(source, target) ||

src/testRunner/unittests/tscWatch/incremental.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ namespace ts.tscWatch {
196196
length: 1,
197197
code: Diagnostics.Type_0_is_not_assignable_to_type_1.code,
198198
category: Diagnostics.Type_0_is_not_assignable_to_type_1.category,
199-
messageText: "Type '20' is not assignable to type 'string'.",
199+
messageText: "Type 'number' is not assignable to type 'string'.",
200200
relatedInformation: undefined,
201201
reportsUnnecessary: undefined,
202202
source: undefined

src/testRunner/unittests/tscWatch/resolutionCache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace ts.tscWatch {
3737
// ensure file has correct number of errors after edit
3838
checkOutputErrorsIncremental(host, [
3939
f1IsNotModule,
40-
getDiagnosticOfFileFromProgram(watch.getCurrentProgram().getProgram(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, 1, "string"),
40+
getDiagnosticOfFileFromProgram(watch.getCurrentProgram().getProgram(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, "number", "string"),
4141
cannotFindFoo
4242
]);
4343
}

src/testRunner/unittests/tsserver/openFile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ bar();`
175175
file,
176176
syntax: [],
177177
semantic: [
178-
createDiagnostic(locationOfY.start, locationOfY.end, Diagnostics.Type_0_is_not_assignable_to_type_1, ["10", "string"]),
178+
createDiagnostic(locationOfY.start, locationOfY.end, Diagnostics.Type_0_is_not_assignable_to_type_1, ["number", "string"]),
179179
],
180180
suggestion: []
181181
},

src/testRunner/unittests/tsserver/projectReferenceErrors.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ fnErr();
166166
{ line: 6, offset: 12 },
167167
{ line: 6, offset: 13 },
168168
Diagnostics.Type_0_is_not_assignable_to_type_1,
169-
["10", "string"],
169+
["number", "string"],
170170
"error",
171171
)
172172
],
@@ -235,7 +235,7 @@ fnErr();
235235
{ line: 6, offset: 5 },
236236
{ line: 6, offset: 6 },
237237
Diagnostics.Type_0_is_not_assignable_to_type_1,
238-
["10", "string"],
238+
["number", "string"],
239239
"error",
240240
)
241241
],
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,6): error TS2461: Type 'string | number' is not an array type.
2-
tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,7): error TS2322: Type '1' is not assignable to type 'string'.
3-
tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,14): error TS2322: Type '""' is not assignable to type 'number'.
2+
tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,7): error TS2322: Type 'number' is not assignable to type 'string'.
3+
tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,14): error TS2322: Type 'string' is not assignable to type 'number'.
44

55

66
==== tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts (3 errors) ====
@@ -10,9 +10,9 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of30.ts(3,14): error
1010
~~~~~~~~~~~~~~~
1111
!!! error TS2461: Type 'string | number' is not an array type.
1212
~
13-
!!! error TS2322: Type '1' is not assignable to type 'string'.
13+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
1414
~
15-
!!! error TS2322: Type '""' is not assignable to type 'number'.
15+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
1616
a;
1717
b;
1818
}

tests/baselines/reference/accessors_spec_section-4.5_error-cases.errors.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(2,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
22
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(3,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
3-
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(3,48): error TS2322: Type '""' is not assignable to type 'number'.
3+
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(3,48): error TS2322: Type 'string' is not assignable to type 'number'.
44
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(5,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
5-
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(5,47): error TS2322: Type '""' is not assignable to type 'number'.
5+
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(5,47): error TS2322: Type 'string' is not assignable to type 'number'.
66
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(6,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
77
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(8,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
88
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(9,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
9-
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(9,52): error TS2322: Type '0' is not assignable to type 'string'.
9+
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(9,52): error TS2322: Type 'number' is not assignable to type 'string'.
1010
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(11,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
11-
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(11,51): error TS2322: Type '0' is not assignable to type 'string'.
11+
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(11,51): error TS2322: Type 'number' is not assignable to type 'string'.
1212
tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(12,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
1313

1414

@@ -21,13 +21,13 @@ tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(12,16): error TS1
2121
~~~~~~~~~~~~~~~~~~~~~~~~~~~
2222
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
2323
~~~~~~~~~~
24-
!!! error TS2322: Type '""' is not assignable to type 'number'.
24+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
2525

2626
public get AnnotatedSetter_SetterLast() { return ""; }
2727
~~~~~~~~~~~~~~~~~~~~~~~~~~
2828
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
2929
~~~~~~~~~~
30-
!!! error TS2322: Type '""' is not assignable to type 'number'.
30+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
3131
public set AnnotatedSetter_SetterLast(a: number) { }
3232
~~~~~~~~~~~~~~~~~~~~~~~~~~
3333
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
@@ -39,13 +39,13 @@ tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts(12,16): error TS1
3939
~~~~~~~~~~~~~~~~~~~~~~~~~~~
4040
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
4141
~~~~
42-
!!! error TS2322: Type '0' is not assignable to type 'string'.
42+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
4343

4444
public set AnnotatedGetter_GetterLast(aStr) { aStr = 0; }
4545
~~~~~~~~~~~~~~~~~~~~~~~~~~
4646
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
4747
~~~~
48-
!!! error TS2322: Type '0' is not assignable to type 'string'.
48+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
4949
public get AnnotatedGetter_GetterLast(): string { return ""; }
5050
~~~~~~~~~~~~~~~~~~~~~~~~~~
5151
!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.

tests/baselines/reference/aliasAssignments.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/aliasAssignments_1.ts(3,1): error TS2322: Type '1' is not assignable to type 'typeof import("tests/cases/compiler/aliasAssignments_moduleA")'.
1+
tests/cases/compiler/aliasAssignments_1.ts(3,1): error TS2322: Type 'number' is not assignable to type 'typeof import("tests/cases/compiler/aliasAssignments_moduleA")'.
22
tests/cases/compiler/aliasAssignments_1.ts(5,1): error TS2322: Type 'typeof import("tests/cases/compiler/aliasAssignments_moduleA")' is not assignable to type 'number'.
33

44

@@ -7,7 +7,7 @@ tests/cases/compiler/aliasAssignments_1.ts(5,1): error TS2322: Type 'typeof impo
77
var x = moduleA;
88
x = 1; // Should be error
99
~
10-
!!! error TS2322: Type '1' is not assignable to type 'typeof import("tests/cases/compiler/aliasAssignments_moduleA")'.
10+
!!! error TS2322: Type 'number' is not assignable to type 'typeof import("tests/cases/compiler/aliasAssignments_moduleA")'.
1111
var y = 1;
1212
y = moduleA; // should be error
1313
~

tests/baselines/reference/allowJscheckJsTypeParameterNoCrash.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/app.js(6,7): error TS2322: Type '1' is not assignable to type 'WatchHandler<any>'.
1+
tests/cases/compiler/app.js(6,7): error TS2322: Type 'number' is not assignable to type 'WatchHandler<any>'.
22

33

44
==== tests/cases/compiler/func.ts (0 errors) ====
@@ -16,7 +16,7 @@ tests/cases/compiler/app.js(6,7): error TS2322: Type '1' is not assignable to ty
1616
data1(val) {
1717
this.data2 = 1;
1818
~~~~~~~~~~
19-
!!! error TS2322: Type '1' is not assignable to type 'WatchHandler<any>'.
19+
!!! error TS2322: Type 'number' is not assignable to type 'WatchHandler<any>'.
2020
},
2121
data2(val) { },
2222
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
tests/cases/compiler/argumentsBindsToFunctionScopeArgumentList.ts(3,5): error TS2322: Type '10' is not assignable to type 'IArguments'.
1+
tests/cases/compiler/argumentsBindsToFunctionScopeArgumentList.ts(3,5): error TS2322: Type 'number' is not assignable to type 'IArguments'.
22

33

44
==== tests/cases/compiler/argumentsBindsToFunctionScopeArgumentList.ts (1 errors) ====
55
var arguments = 10;
66
function foo(a) {
77
arguments = 10; /// This shouldnt be of type number and result in error.
88
~~~~~~~~~
9-
!!! error TS2322: Type '10' is not assignable to type 'IArguments'.
9+
!!! error TS2322: Type 'number' is not assignable to type 'IArguments'.
1010
}

0 commit comments

Comments
 (0)