-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Normalize type references before relating them #35266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
c73affd
b1cb35a
99bcfb3
2e432ec
0d99ec1
4bd698b
88d0315
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts(45,7): error TS2322: Type '42' is not assignable to type 'Box2'. | ||
tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts(45,7): error TS2322: Type '42' is not assignable to type 'Box<number | Box2>'. | ||
tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts(60,7): error TS2322: Type 'number' is not assignable to type 'string | RecArray<string>'. | ||
tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts(66,8): error TS2322: Type 'number' is not assignable to type 'string | string[]'. | ||
tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts(72,8): error TS2322: Type 'number' is not assignable to type 'string | (string | string[])[]'. | ||
|
@@ -60,7 +60,7 @@ tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeRefe | |
|
||
const b20: Box2 = 42; // Error | ||
~~~ | ||
!!! error TS2322: Type '42' is not assignable to type 'Box2'. | ||
!!! error TS2322: Type '42' is not assignable to type 'Box<number | Box2>'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😦 Is it possible we want to keep the pre-normalized form around for error reporting? Since it might have a nicer alias for us to use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked at doing that, but I'm not sure it really is all that valuable. We still display the alias in all other situations, it's only when we're elaborating into the type that we now display structure one level earlier that we would before. I think the few places it affects are just as well served with the change in this PR (which, BTW, is what we used to always do). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know, but we acknowledged that these errors were better - a nice side effect of the recursive alias change. it would be nice if we could keep them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, changed the code to preserve the original type and use it in error reporting if it has an alias. |
||
const b21: Box2 = { value: 42 }; | ||
const b22: Box2 = { value: { value: { value: 42 }}}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//// [unwitnessedTypeParameterVariance.ts] | ||
// Repros from #33872 | ||
|
||
export interface CalcObj<O> { | ||
read: (origin: O) => CalcValue<O>; | ||
} | ||
|
||
export type CalcValue<O> = CalcObj<O>; | ||
|
||
function foo<O>() { | ||
const unk: CalcObj<unknown> = { read: (origin: unknown) => unk } | ||
const x: CalcObj<O> = unk; | ||
} | ||
|
||
type A<T> = B<T>; | ||
|
||
interface B<T> { | ||
prop: A<T>; | ||
} | ||
|
||
declare let a: A<number>; | ||
declare let b: A<3>; | ||
|
||
b = a; | ||
|
||
|
||
//// [unwitnessedTypeParameterVariance.js] | ||
"use strict"; | ||
// Repros from #33872 | ||
exports.__esModule = true; | ||
function foo() { | ||
var unk = { read: function (origin) { return unk; } }; | ||
var x = unk; | ||
} | ||
b = a; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
=== tests/cases/compiler/unwitnessedTypeParameterVariance.ts === | ||
// Repros from #33872 | ||
|
||
export interface CalcObj<O> { | ||
>CalcObj : Symbol(CalcObj, Decl(unwitnessedTypeParameterVariance.ts, 0, 0)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 2, 25)) | ||
|
||
read: (origin: O) => CalcValue<O>; | ||
>read : Symbol(CalcObj.read, Decl(unwitnessedTypeParameterVariance.ts, 2, 29)) | ||
>origin : Symbol(origin, Decl(unwitnessedTypeParameterVariance.ts, 3, 11)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 2, 25)) | ||
>CalcValue : Symbol(CalcValue, Decl(unwitnessedTypeParameterVariance.ts, 4, 1)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 2, 25)) | ||
} | ||
|
||
export type CalcValue<O> = CalcObj<O>; | ||
>CalcValue : Symbol(CalcValue, Decl(unwitnessedTypeParameterVariance.ts, 4, 1)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 6, 22)) | ||
>CalcObj : Symbol(CalcObj, Decl(unwitnessedTypeParameterVariance.ts, 0, 0)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 6, 22)) | ||
|
||
function foo<O>() { | ||
>foo : Symbol(foo, Decl(unwitnessedTypeParameterVariance.ts, 6, 38)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 8, 13)) | ||
|
||
const unk: CalcObj<unknown> = { read: (origin: unknown) => unk } | ||
>unk : Symbol(unk, Decl(unwitnessedTypeParameterVariance.ts, 9, 9)) | ||
>CalcObj : Symbol(CalcObj, Decl(unwitnessedTypeParameterVariance.ts, 0, 0)) | ||
>read : Symbol(read, Decl(unwitnessedTypeParameterVariance.ts, 9, 35)) | ||
>origin : Symbol(origin, Decl(unwitnessedTypeParameterVariance.ts, 9, 43)) | ||
>unk : Symbol(unk, Decl(unwitnessedTypeParameterVariance.ts, 9, 9)) | ||
|
||
const x: CalcObj<O> = unk; | ||
>x : Symbol(x, Decl(unwitnessedTypeParameterVariance.ts, 10, 9)) | ||
>CalcObj : Symbol(CalcObj, Decl(unwitnessedTypeParameterVariance.ts, 0, 0)) | ||
>O : Symbol(O, Decl(unwitnessedTypeParameterVariance.ts, 8, 13)) | ||
>unk : Symbol(unk, Decl(unwitnessedTypeParameterVariance.ts, 9, 9)) | ||
} | ||
|
||
type A<T> = B<T>; | ||
>A : Symbol(A, Decl(unwitnessedTypeParameterVariance.ts, 11, 1)) | ||
>T : Symbol(T, Decl(unwitnessedTypeParameterVariance.ts, 13, 7)) | ||
>B : Symbol(B, Decl(unwitnessedTypeParameterVariance.ts, 13, 17)) | ||
>T : Symbol(T, Decl(unwitnessedTypeParameterVariance.ts, 13, 7)) | ||
|
||
interface B<T> { | ||
>B : Symbol(B, Decl(unwitnessedTypeParameterVariance.ts, 13, 17)) | ||
>T : Symbol(T, Decl(unwitnessedTypeParameterVariance.ts, 15, 12)) | ||
|
||
prop: A<T>; | ||
>prop : Symbol(B.prop, Decl(unwitnessedTypeParameterVariance.ts, 15, 16)) | ||
>A : Symbol(A, Decl(unwitnessedTypeParameterVariance.ts, 11, 1)) | ||
>T : Symbol(T, Decl(unwitnessedTypeParameterVariance.ts, 15, 12)) | ||
} | ||
|
||
declare let a: A<number>; | ||
>a : Symbol(a, Decl(unwitnessedTypeParameterVariance.ts, 19, 11)) | ||
>A : Symbol(A, Decl(unwitnessedTypeParameterVariance.ts, 11, 1)) | ||
|
||
declare let b: A<3>; | ||
>b : Symbol(b, Decl(unwitnessedTypeParameterVariance.ts, 20, 11)) | ||
>A : Symbol(A, Decl(unwitnessedTypeParameterVariance.ts, 11, 1)) | ||
|
||
b = a; | ||
>b : Symbol(b, Decl(unwitnessedTypeParameterVariance.ts, 20, 11)) | ||
>a : Symbol(a, Decl(unwitnessedTypeParameterVariance.ts, 19, 11)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
=== tests/cases/compiler/unwitnessedTypeParameterVariance.ts === | ||
// Repros from #33872 | ||
|
||
export interface CalcObj<O> { | ||
read: (origin: O) => CalcValue<O>; | ||
>read : (origin: O) => CalcValue<O> | ||
>origin : O | ||
} | ||
|
||
export type CalcValue<O> = CalcObj<O>; | ||
>CalcValue : CalcValue<O> | ||
|
||
function foo<O>() { | ||
>foo : <O>() => void | ||
|
||
const unk: CalcObj<unknown> = { read: (origin: unknown) => unk } | ||
>unk : CalcObj<unknown> | ||
>{ read: (origin: unknown) => unk } : { read: (origin: unknown) => CalcObj<unknown>; } | ||
>read : (origin: unknown) => CalcObj<unknown> | ||
>(origin: unknown) => unk : (origin: unknown) => CalcObj<unknown> | ||
>origin : unknown | ||
>unk : CalcObj<unknown> | ||
|
||
const x: CalcObj<O> = unk; | ||
>x : CalcObj<O> | ||
>unk : CalcObj<unknown> | ||
} | ||
|
||
type A<T> = B<T>; | ||
>A : A<T> | ||
|
||
interface B<T> { | ||
prop: A<T>; | ||
>prop : A<T> | ||
} | ||
|
||
declare let a: A<number>; | ||
>a : A<number> | ||
|
||
declare let b: A<3>; | ||
>b : A<3> | ||
|
||
b = a; | ||
>b = a : A<number> | ||
>b : A<3> | ||
>a : A<number> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// @strict: true | ||
|
||
// Repros from #33872 | ||
|
||
export interface CalcObj<O> { | ||
read: (origin: O) => CalcValue<O>; | ||
} | ||
|
||
export type CalcValue<O> = CalcObj<O>; | ||
|
||
function foo<O>() { | ||
const unk: CalcObj<unknown> = { read: (origin: unknown) => unk } | ||
const x: CalcObj<O> = unk; | ||
} | ||
|
||
type A<T> = B<T>; | ||
|
||
interface B<T> { | ||
prop: A<T>; | ||
} | ||
|
||
declare let a: A<number>; | ||
declare let b: A<3>; | ||
|
||
b = a; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will this function jibe with #31804 and the associated fix #32116 - does this function just become recursive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to just move the loop into
getNormalizedType
.