TypeScript/tests/cases/compiler/varianceMeasurement.ts
Anders Hejlsberg 1a10e712e6
Improve variance measurement (#36261)
* No covariance default for recursive references in variance measurement

* Add tests

* Accept new baselines
2020-01-17 11:50:38 -08:00

65 lines
1.4 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