• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// @strict: true
2// @declaration: true
3
4type Covariant<out T> = {
5    x: T;
6}
7
8declare let super_covariant: Covariant<unknown>;
9declare let sub_covariant: Covariant<string>;
10
11super_covariant = sub_covariant;
12sub_covariant = super_covariant;  // Error
13
14type Contravariant<in T> = {
15    f: (x: T) => void;
16}
17
18declare let super_contravariant: Contravariant<unknown>;
19declare let sub_contravariant: Contravariant<string>;
20
21super_contravariant = sub_contravariant;  // Error
22sub_contravariant = super_contravariant;
23
24type Invariant<in out T> = {
25    f: (x: T) => T;
26}
27
28declare let super_invariant: Invariant<unknown>;
29declare let sub_invariant: Invariant<string>;
30
31super_invariant = sub_invariant;  // Error
32sub_invariant = super_invariant;  // Error
33
34// Variance of various type constructors
35
36type T10<out T> = T;
37type T11<in T> = keyof T;
38type T12<out T, out K extends keyof T> = T[K];
39type T13<in out T> = T[keyof T];
40
41// Variance annotation errors
42
43type Covariant1<in T> = {  // Error
44    x: T;
45}
46
47type Contravariant1<out T> = keyof T;  // Error
48
49type Contravariant2<out T> = {  // Error
50    f: (x: T) => void;
51}
52
53type Invariant1<in T> = {  // Error
54    f: (x: T) => T;
55}
56
57type Invariant2<out T> = {  // Error
58    f: (x: T) => T;
59}
60
61// Variance in circular types
62
63type Foo1<in T> = {  // Error
64    x: T;
65    f: FooFn1<T>;
66}
67
68type FooFn1<T> = (foo: Bar1<T[]>) => void;
69
70type Bar1<T> = {
71    value: Foo1<T[]>;
72}
73
74type Foo2<out T> = {  // Error
75    x: T;
76    f: FooFn2<T>;
77}
78
79type FooFn2<T> = (foo: Bar2<T[]>) => void;
80
81type Bar2<T> = {
82    value: Foo2<T[]>;
83}
84
85type Foo3<in out T> = {
86    x: T;
87    f: FooFn3<T>;
88}
89
90type FooFn3<T> = (foo: Bar3<T[]>) => void;
91
92type Bar3<T> = {
93    value: Foo3<T[]>;
94}
95
96// Wrong modifier usage
97
98type T20<public T> = T;  // Error
99type T21<in out in T> = T;  // Error
100type T22<in out out T> = T;  // Error
101type T23<out in T> = T;  // Error
102
103declare function f1<in T>(x: T): void;  // Error
104declare function f2<out T>(): T;  // Error
105
106class C {
107    in a = 0;  // Error
108    out b = 0;  // Error
109}
110
111// Interface merging
112
113interface Baz<out T> {}
114interface Baz<in T> {}
115
116declare let baz1: Baz<unknown>;
117declare let baz2: Baz<string>;
118
119baz1 = baz2;  // Error
120baz2 = baz1;  // Error
121
122// Repro from #44572
123
124interface Parent<out A> {
125    child: Child<A> | null;
126    parent: Parent<A> | null;
127}
128
129interface Child<A, B = unknown> extends Parent<A> {
130    readonly a: A;
131    readonly b: B;
132}
133
134function fn<A>(inp: Child<A>) {
135    const a: Child<unknown> = inp;
136}
137
138const pu: Parent<unknown> = { child: { a: 0, b: 0, child: null, parent: null }, parent: null };
139const notString: Parent<string> = pu;  // Error
140
141// Repro from comment in #44572
142
143declare class StateNode<TContext, in out TEvent extends { type: string }> {
144    _storedEvent: TEvent;
145    _action: ActionObject<TEvent>;
146    _state: StateNode<TContext, any>;
147}
148
149interface ActionObject<TEvent extends { type: string }> {
150    exec: (meta: StateNode<any, TEvent>) => void;
151}
152
153declare function createMachine<TEvent extends { type: string }>(action: ActionObject<TEvent>): StateNode<any, any>;
154
155declare function interpret<TContext>(machine: StateNode<TContext, any>): void;
156
157const machine = createMachine({} as any);
158
159interpret(machine);
160
161declare const qq: ActionObject<{ type: "PLAY"; value: number }>;
162
163createMachine<{ type: "PLAY"; value: number } | { type: "RESET" }>(qq);  // Error
164
165// Repros from #48618
166
167let Anon = class <out T> {
168    foo(): InstanceType<(typeof Anon<T>)> {
169        return this;
170    }
171}
172
173let OuterC = class C<out T> {
174    foo(): C<T> {
175        return this;
176    }
177}
178