Skip to content

Commit

Permalink
Add regression test
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Aug 29, 2021
1 parent 2d5ba1b commit a1f82c1
Show file tree
Hide file tree
Showing 5 changed files with 429 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(24,1): error TS2322: Type 'Parent1<unknown>' is not assignable to type 'Parent1<string>'.
Type 'unknown' is not assignable to type 'string'.
tests/cases/compiler/checkOrderDependenceGenericAssignability.ts(51,1): error TS2322: Type 'Parent2<unknown>' is not assignable to type 'Parent2<string>'.
Type 'unknown' is not assignable to type 'string'.


==== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts (2 errors) ====
// Repro from #44572 with interface types

interface Parent1<A> {
child: Child1<A>;
parent: Parent1<A>;
}

interface Child1<A, B = unknown> extends Parent1<A> {
readonly a: A;
// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
}

function fn1<A>(inp: Child1<A>) {
// This assignability check defeats the later one
const a: Child1<unknown> = inp;
}

declare let pu1: Parent1<unknown>;
declare let ps1: Parent1<string>;

pu1 = ps1; // Ok
ps1 = pu1; // Error expected
~~~
!!! error TS2322: Type 'Parent1<unknown>' is not assignable to type 'Parent1<string>'.
!!! error TS2322: Type 'unknown' is not assignable to type 'string'.

// Repro from #44572 with aliased object types

type Parent2<A> = {
child: Child2<A>;
parent: Parent2<A>;
}

type Child2<A, B = unknown> = {
child: Child2<A>;
parent: Parent2<A>;
readonly a: A;
// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
}

function fn2<A>(inp: Child2<A>) {
// This assignability check defeats the later one
const a: Child2<unknown> = inp;
}

declare let pu2: Parent2<unknown>;
declare let ps2: Parent2<string>;

pu2 = ps2; // Ok
ps2 = pu2; // Error expected
~~~
!!! error TS2322: Type 'Parent2<unknown>' is not assignable to type 'Parent2<string>'.
!!! error TS2322: Type 'unknown' is not assignable to type 'string'.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//// [checkOrderDependenceGenericAssignability.ts]
// Repro from #44572 with interface types

interface Parent1<A> {
child: Child1<A>;
parent: Parent1<A>;
}

interface Child1<A, B = unknown> extends Parent1<A> {
readonly a: A;
// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
}

function fn1<A>(inp: Child1<A>) {
// This assignability check defeats the later one
const a: Child1<unknown> = inp;
}

declare let pu1: Parent1<unknown>;
declare let ps1: Parent1<string>;

pu1 = ps1; // Ok
ps1 = pu1; // Error expected

// Repro from #44572 with aliased object types

type Parent2<A> = {
child: Child2<A>;
parent: Parent2<A>;
}

type Child2<A, B = unknown> = {
child: Child2<A>;
parent: Parent2<A>;
readonly a: A;
// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
}

function fn2<A>(inp: Child2<A>) {
// This assignability check defeats the later one
const a: Child2<unknown> = inp;
}

declare let pu2: Parent2<unknown>;
declare let ps2: Parent2<string>;

pu2 = ps2; // Ok
ps2 = pu2; // Error expected


//// [checkOrderDependenceGenericAssignability.js]
"use strict";
// Repro from #44572 with interface types
function fn1(inp) {
// This assignability check defeats the later one
var a = inp;
}
pu1 = ps1; // Ok
ps1 = pu1; // Error expected
function fn2(inp) {
// This assignability check defeats the later one
var a = inp;
}
pu2 = ps2; // Ok
ps2 = pu2; // Error expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
=== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts ===
// Repro from #44572 with interface types

interface Parent1<A> {
>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18))

child: Child1<A>;
>child : Symbol(Parent1.child, Decl(checkOrderDependenceGenericAssignability.ts, 2, 22))
>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18))

parent: Parent1<A>;
>parent : Symbol(Parent1.parent, Decl(checkOrderDependenceGenericAssignability.ts, 3, 21))
>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 2, 18))
}

interface Child1<A, B = unknown> extends Parent1<A> {
>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17))
>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 7, 19))
>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17))

readonly a: A;
>a : Symbol(Child1.a, Decl(checkOrderDependenceGenericAssignability.ts, 7, 53))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 7, 17))

// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
>b : Symbol(Child1.b, Decl(checkOrderDependenceGenericAssignability.ts, 8, 18))
>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 7, 19))
}

function fn1<A>(inp: Child1<A>) {
>fn1 : Symbol(fn1, Decl(checkOrderDependenceGenericAssignability.ts, 12, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 14, 13))
>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 14, 16))
>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 14, 13))

// This assignability check defeats the later one
const a: Child1<unknown> = inp;
>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 16, 9))
>Child1 : Symbol(Child1, Decl(checkOrderDependenceGenericAssignability.ts, 5, 1))
>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 14, 16))
}

declare let pu1: Parent1<unknown>;
>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 19, 11))
>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0))

declare let ps1: Parent1<string>;
>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 20, 11))
>Parent1 : Symbol(Parent1, Decl(checkOrderDependenceGenericAssignability.ts, 0, 0))

pu1 = ps1; // Ok
>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 19, 11))
>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 20, 11))

ps1 = pu1; // Error expected
>ps1 : Symbol(ps1, Decl(checkOrderDependenceGenericAssignability.ts, 20, 11))
>pu1 : Symbol(pu1, Decl(checkOrderDependenceGenericAssignability.ts, 19, 11))

// Repro from #44572 with aliased object types

type Parent2<A> = {
>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 23, 10))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 27, 13))

child: Child2<A>;
>child : Symbol(child, Decl(checkOrderDependenceGenericAssignability.ts, 27, 19))
>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 30, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 27, 13))

parent: Parent2<A>;
>parent : Symbol(parent, Decl(checkOrderDependenceGenericAssignability.ts, 28, 21))
>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 23, 10))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 27, 13))
}

type Child2<A, B = unknown> = {
>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 30, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 32, 12))
>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 32, 14))

child: Child2<A>;
>child : Symbol(child, Decl(checkOrderDependenceGenericAssignability.ts, 32, 31))
>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 30, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 32, 12))

parent: Parent2<A>;
>parent : Symbol(parent, Decl(checkOrderDependenceGenericAssignability.ts, 33, 21))
>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 23, 10))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 32, 12))

readonly a: A;
>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 34, 23))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 32, 12))

// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
>b : Symbol(b, Decl(checkOrderDependenceGenericAssignability.ts, 35, 18))
>B : Symbol(B, Decl(checkOrderDependenceGenericAssignability.ts, 32, 14))
}

function fn2<A>(inp: Child2<A>) {
>fn2 : Symbol(fn2, Decl(checkOrderDependenceGenericAssignability.ts, 39, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 41, 13))
>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 41, 16))
>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 30, 1))
>A : Symbol(A, Decl(checkOrderDependenceGenericAssignability.ts, 41, 13))

// This assignability check defeats the later one
const a: Child2<unknown> = inp;
>a : Symbol(a, Decl(checkOrderDependenceGenericAssignability.ts, 43, 9))
>Child2 : Symbol(Child2, Decl(checkOrderDependenceGenericAssignability.ts, 30, 1))
>inp : Symbol(inp, Decl(checkOrderDependenceGenericAssignability.ts, 41, 16))
}

declare let pu2: Parent2<unknown>;
>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 46, 11))
>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 23, 10))

declare let ps2: Parent2<string>;
>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 47, 11))
>Parent2 : Symbol(Parent2, Decl(checkOrderDependenceGenericAssignability.ts, 23, 10))

pu2 = ps2; // Ok
>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 46, 11))
>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 47, 11))

ps2 = pu2; // Error expected
>ps2 : Symbol(ps2, Decl(checkOrderDependenceGenericAssignability.ts, 47, 11))
>pu2 : Symbol(pu2, Decl(checkOrderDependenceGenericAssignability.ts, 46, 11))

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
=== tests/cases/compiler/checkOrderDependenceGenericAssignability.ts ===
// Repro from #44572 with interface types

interface Parent1<A> {
child: Child1<A>;
>child : Child1<A, unknown>

parent: Parent1<A>;
>parent : Parent1<A>
}

interface Child1<A, B = unknown> extends Parent1<A> {
readonly a: A;
>a : A

// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
>b : B
}

function fn1<A>(inp: Child1<A>) {
>fn1 : <A>(inp: Child1<A>) => void
>inp : Child1<A, unknown>

// This assignability check defeats the later one
const a: Child1<unknown> = inp;
>a : Child1<unknown, unknown>
>inp : Child1<A, unknown>
}

declare let pu1: Parent1<unknown>;
>pu1 : Parent1<unknown>

declare let ps1: Parent1<string>;
>ps1 : Parent1<string>

pu1 = ps1; // Ok
>pu1 = ps1 : Parent1<string>
>pu1 : Parent1<unknown>
>ps1 : Parent1<string>

ps1 = pu1; // Error expected
>ps1 = pu1 : Parent1<unknown>
>ps1 : Parent1<string>
>pu1 : Parent1<unknown>

// Repro from #44572 with aliased object types

type Parent2<A> = {
>Parent2 : Parent2<A>

child: Child2<A>;
>child : Child2<A, unknown>

parent: Parent2<A>;
>parent : Parent2<A>
}

type Child2<A, B = unknown> = {
>Child2 : Child2<A, B>

child: Child2<A>;
>child : Child2<A, unknown>

parent: Parent2<A>;
>parent : Parent2<A>

readonly a: A;
>a : A

// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
>b : B
}

function fn2<A>(inp: Child2<A>) {
>fn2 : <A>(inp: Child2<A>) => void
>inp : Child2<A, unknown>

// This assignability check defeats the later one
const a: Child2<unknown> = inp;
>a : Child2<unknown, unknown>
>inp : Child2<A, unknown>
}

declare let pu2: Parent2<unknown>;
>pu2 : Parent2<unknown>

declare let ps2: Parent2<string>;
>ps2 : Parent2<string>

pu2 = ps2; // Ok
>pu2 = ps2 : Parent2<string>
>pu2 : Parent2<unknown>
>ps2 : Parent2<string>

ps2 = pu2; // Error expected
>ps2 = pu2 : Parent2<unknown>
>ps2 : Parent2<string>
>pu2 : Parent2<unknown>

Loading

0 comments on commit a1f82c1

Please sign in to comment.