TypeScript/tests/cases/compiler/varianceMeasurement.ts
Anders Hejlsberg f9dcd9ef98
Don't cache Ternary.Maybe results when recursion is encountered during variance measurement (#41218)
* Don't record Ternary.Maybe results in cache during recursive variance measurement

* Add regression test

* Accept new baselines

* Use Ternary.Unknown to signal variance recursion

* Add comments

* Fix comment
2020-10-27 10:53:13 -07:00

78 lines
1.6 KiB
TypeScript

// @strict: true
// The type below should be invariant in T but is measured as covariant because
// we don't analyze recursive references.
interface Foo1<T> {
x: T;
y: Foo1<(arg: T) => void>;
}
declare const f10: Foo1<string>;
const f11: Foo1<'a'> = f10;
const f12: Foo1<unknown> = f10;
// The type below is invariant in T and is measured as such.
interface Foo2<T> {
x: T;
y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; }
}
declare const f20: Foo2<string>;
const f21: Foo2<'a'> = f20;
const f22: Foo2<unknown> = f20;
// The type below should be invariant in T but is measured as covariant because
// we don't analyze recursive references.
type Foo3<T> = {
x: T;
y: Foo3<(arg: T) => void>;
}
declare const f30: Foo3<string>;
const f31: Foo3<'a'> = f30;
const f32: Foo3<unknown> = f30;
// The type below is invariant in T and is measured as such.
type Foo4<T> = {
x: T;
y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; }
}
declare const f40: Foo4<string>;
const f41: Foo4<'a'> = f40;
const f42: Foo4<unknown> = f40;
// Repro from #3580
interface Fn<A, B> {
(a: A): B;
then<C>(next: Fn<B, C>): Fn<A, C>;
}
declare const fn: Fn<string, number>;
// Contravariant in A
const fn1: Fn<unknown, number> = fn; // Error
const fn2: Fn<'a', number> = fn;
// Covariant in B
const fn3: Fn<string, unknown> = fn;
const fn4: Fn<string, 0> = fn; // Error
// Repro from #39947
interface I<Dummy, V> {
c: C<Dummy, V>;
}
class C<Dummy, V> {
declare sub: I<Dummy, V>;
declare covariance: V;
}
const c1: C<unknown, string> = new C<unknown, number>(); // Error