Skip to content

Commit

Permalink
Don't generalize when assigment target is never (fix: #41707) (#59774)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyzyla authored Aug 29, 2024
1 parent 342d142 commit eadb9e1
Show file tree
Hide file tree
Showing 30 changed files with 197 additions and 78 deletions.
6 changes: 4 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22056,8 +22056,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target);
let generalizedSource = source;
let generalizedSourceType = sourceType;

if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) {

// Don't generalize on 'never' - we really want the original type
// to be displayed for use-cases like 'assertNever'.
if (!(target.flags & TypeFlags.Never) && isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) {
generalizedSource = getBaseTypeOfLiteralType(source);
Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable");
generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource);
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/controlFlowArrayErrors.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ controlFlowArrayErrors.ts(19,9): error TS7034: Variable 'x' implicitly has type
controlFlowArrayErrors.ts(22,9): error TS7005: Variable 'x' implicitly has an 'any[]' type.
controlFlowArrayErrors.ts(29,12): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string | number'.
controlFlowArrayErrors.ts(34,12): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string | number'.
controlFlowArrayErrors.ts(48,12): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
controlFlowArrayErrors.ts(48,12): error TS2345: Argument of type '99' is not assignable to parameter of type 'never'.
controlFlowArrayErrors.ts(56,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
controlFlowArrayErrors.ts(60,11): error TS7034: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined.
controlFlowArrayErrors.ts(63,9): error TS7005: Variable 'x' implicitly has an 'any[]' type.
Expand Down Expand Up @@ -78,7 +78,7 @@ controlFlowArrayErrors.ts(63,9): error TS7005: Variable 'x' implicitly has an 'a
x; // boolean[] | (string | number)[]
x.push(99); // Error
~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '99' is not assignable to parameter of type 'never'.
}

function f7() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependentDestructuredVariables.ts(334,5): error TS7022: 'value1' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
dependentDestructuredVariables.ts(334,5): error TS7031: Binding element 'value1' implicitly has an 'any' type.
dependentDestructuredVariables.ts(431,15): error TS2322: Type 'number' is not assignable to type 'never'.
dependentDestructuredVariables.ts(431,15): error TS2322: Type '1' is not assignable to type 'never'.


==== dependentDestructuredVariables.ts (3 errors) ====
Expand Down Expand Up @@ -440,7 +440,7 @@ dependentDestructuredVariables.ts(431,15): error TS2322: Type 'number' is not as
if (y === undefined) {
const shouldNotBeOk: never = x; // Error
~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
!!! error TS2322: Type '1' is not assignable to type 'never'.
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ foo.js(16,60): error TS2355: A function whose declared type is neither 'undefine
foo.js(21,20): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
foo.js(31,10): error TS2534: A function returning 'never' cannot have a reachable end point.
foo.js(35,12): error TS1065: The return type of an async function or method must be the global Promise<T> type.
foo.js(37,5): error TS2322: Type 'string' is not assignable to type 'never'.
foo.js(37,5): error TS2322: Type '"asd"' is not assignable to type 'never'.
foo.js(40,56): error TS2534: A function returning 'never' cannot have a reachable end point.
foo.js(45,18): error TS2534: A function returning 'never' cannot have a reachable end point.

Expand Down Expand Up @@ -64,7 +64,7 @@ foo.js(45,18): error TS2534: A function returning 'never' cannot have a reachabl
async function testNever2() {
return "asd";
~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'never'.
!!! error TS2322: Type '"asd"' is not assignable to type 'never'.
}

var testNever3 = /** @type {FunctionReturningNever} */ function() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exhaustiveSwitchCheckCircularity.ts(14,26): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
exhaustiveSwitchCheckCircularity.ts(14,26): error TS2345: Argument of type '"bbb"' is not assignable to parameter of type 'never'.


==== exhaustiveSwitchCheckCircularity.ts (1 errors) ====
Expand All @@ -17,7 +17,7 @@ exhaustiveSwitchCheckCircularity.ts(14,26): error TS2345: Argument of type 'stri
}
else if (isNever(foo)) { // Error expected
~~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '"bbb"' is not assignable to parameter of type 'never'.
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extractInferenceImprovement.ts(26,26): error TS2345: Argument of type 'typeof s' is not assignable to parameter of type 'never'.
extractInferenceImprovement.ts(26,26): error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type 'never'.
extractInferenceImprovement.ts(28,1): error TS2322: Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
extractInferenceImprovement.ts(28,26): error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type '"first" | "second"'.
Expand Down Expand Up @@ -32,7 +32,7 @@ extractInferenceImprovement.ts(28,26): error TS2345: Argument of type 'unique sy
// Should fail
prop = getProperty2(obj, s);
~
!!! error TS2345: Argument of type 'typeof s' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type 'never'.

prop = getProperty3(obj, s);
~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
functionCallOnConstrainedTypeVariable.ts(11,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(15,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(18,5): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(11,7): error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(15,7): error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(18,5): error TS2345: Argument of type '""' is not assignable to parameter of type 'never'.
functionCallOnConstrainedTypeVariable.ts(19,9): error TS2554: Expected 1 arguments, but got 4.


Expand All @@ -17,18 +17,18 @@ functionCallOnConstrainedTypeVariable.ts(19,9): error TS2554: Expected 1 argumen
function call0(p: A | B) {
p.a("s"); // Error
~~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'.
}

function callN<T extends A | B>(p: T) {
p.a("s"); // Error
~~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '"s"' is not assignable to parameter of type 'never'.

var a: T["a"] = p.a;
a(""); // Error
~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '""' is not assignable to parameter of type 'never'.
a("", "", "", ""); // Error
~~~~~~~~~~
!!! error TS2554: Expected 1 arguments, but got 4.
Expand Down
20 changes: 10 additions & 10 deletions tests/baselines/reference/keyofAndIndexedAccess2.errors.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
keyofAndIndexedAccess2.ts(4,5): error TS2322: Type 'string' is not assignable to type 'number'.
keyofAndIndexedAccess2.ts(6,5): error TS2322: Type '2' is not assignable to type '0 | 1'.
keyofAndIndexedAccess2.ts(7,5): error TS2322: Type '"x"' is not assignable to type '0 | 1'.
keyofAndIndexedAccess2.ts(8,5): error TS2322: Type 'number' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(9,5): error TS2322: Type 'number' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(10,5): error TS2322: Type 'string' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(8,5): error TS2322: Type '1' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(9,5): error TS2322: Type '2' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(10,5): error TS2322: Type '"x"' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(14,5): error TS2739: Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y
keyofAndIndexedAccess2.ts(15,5): error TS2322: Type 'T' is not assignable to type '{ x: number; y: number; }'.
Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y
Expand All @@ -18,7 +18,7 @@ keyofAndIndexedAccess2.ts(31,5): error TS2322: Type '{ [key: string]: number; }'
keyofAndIndexedAccess2.ts(38,5): error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'.
keyofAndIndexedAccess2.ts(50,3): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'.
No index signature with a parameter of type 'string' was found on type 'Item'.
keyofAndIndexedAccess2.ts(51,3): error TS2322: Type 'number' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'never'.
keyofAndIndexedAccess2.ts(52,3): error TS2322: Type 'number' is not assignable to type 'T[keyof T]'.
'T[keyof T]' could be instantiated with an arbitrary type which could be unrelated to 'number'.
keyofAndIndexedAccess2.ts(53,3): error TS2322: Type 'number' is not assignable to type 'T[K]'.
Expand All @@ -30,7 +30,7 @@ keyofAndIndexedAccess2.ts(67,3): error TS2322: Type 'number' is not assignable t
keyofAndIndexedAccess2.ts(68,3): error TS2322: Type 'number' is not assignable to type 'T[K]'.
'number' is assignable to the constraint of type 'T[K]', but 'T[K]' could be instantiated with a different subtype of constraint 'number'.
keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to type 'Type[K]'.
Type 'number' is not assignable to type 'never'.
Type '123' is not assignable to type 'never'.


==== keyofAndIndexedAccess2.ts (23 errors) ====
Expand All @@ -49,13 +49,13 @@ keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to
!!! error TS2322: Type '"x"' is not assignable to type '0 | 1'.
obj[k2] = 1; // Error
~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
!!! error TS2322: Type '1' is not assignable to type 'never'.
obj[k2] = 2; // Error
~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
!!! error TS2322: Type '2' is not assignable to type 'never'.
obj[k2] = 'x'; // Error
~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'never'.
!!! error TS2322: Type '"x"' is not assignable to type 'never'.
}

function f2<T extends { [key: string]: number }>(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) {
Expand Down Expand Up @@ -121,7 +121,7 @@ keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to
!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'Item'.
obj[k2] = 123; // Error
~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
!!! error TS2322: Type '123' is not assignable to type 'never'.
obj[k3] = 123; // Error
~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'T[keyof T]'.
Expand Down Expand Up @@ -197,7 +197,7 @@ keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to
return 123; // Error
~~~~~~
!!! error TS2322: Type '123' is not assignable to type 'Type[K]'.
!!! error TS2322: Type 'number' is not assignable to type 'never'.
!!! error TS2322: Type '123' is not assignable to type 'never'.
}

// Repro from #30920
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment6.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment6.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment6.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment6.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment6.ts(10,42): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment7.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment7.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment7.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.


==== logicalAssignment7.ts (2 errors) ====
Expand All @@ -16,6 +16,6 @@ logicalAssignment7.ts(10,40): error TS2345: Argument of type 'number' is not ass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'.
}

Loading

0 comments on commit eadb9e1

Please sign in to comment.