File: strictFunctionTypesErrors.ts

package info (click to toggle)
node-typescript 3.3.3333-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 324,548 kB
  • sloc: makefile: 6; sh: 3
file content (157 lines) | stat: -rw-r--r-- 3,557 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
export {}

// @strict: true

declare let f1: (x: Object) => Object;
declare let f2: (x: Object) => string;
declare let f3: (x: string) => Object;
declare let f4: (x: string) => string;

f1 = f2;  // Ok
f1 = f3;  // Error
f1 = f4;  // Error

f2 = f1;  // Error
f2 = f3;  // Error
f2 = f4;  // Error

f3 = f1;  // Ok
f3 = f2;  // Ok
f3 = f4;  // Ok

f4 = f1;  // Error
f4 = f2;  // Ok
f4 = f3;  // Error

type Func<T, U> = (x: T) => U;

declare let g1: Func<Object, Object>;
declare let g2: Func<Object, string>;
declare let g3: Func<string, Object>;
declare let g4: Func<string, string>;

g1 = g2;  // Ok
g1 = g3;  // Error
g1 = g4;  // Error

g2 = g1;  // Error
g2 = g3;  // Error
g2 = g4;  // Error

g3 = g1;  // Ok
g3 = g2;  // Ok
g3 = g4;  // Ok

g4 = g1;  // Error
g4 = g2;  // Ok
g4 = g3;  // Error

declare let h1: Func<Func<Object, void>, Object>;
declare let h2: Func<Func<Object, void>, string>;
declare let h3: Func<Func<string, void>, Object>;
declare let h4: Func<Func<string, void>, string>;

h1 = h2;  // Ok
h1 = h3;  // Ok
h1 = h4;  // Ok

h2 = h1;  // Error
h2 = h3;  // Error
h2 = h4;  // Ok

h3 = h1;  // Error
h3 = h2;  // Error
h3 = h4;  // Ok

h4 = h1;  // Error
h4 = h2;  // Error
h4 = h3;  // Error

declare let i1: Func<Object, Func<Object, void>>;
declare let i2: Func<Object, Func<string, void>>;
declare let i3: Func<string, Func<Object, void>>;
declare let i4: Func<string, Func<string, void>>;

i1 = i2;  // Error
i1 = i3;  // Error
i1 = i4;  // Error

i2 = i1;  // Ok
i2 = i3;  // Error
i2 = i4;  // Error

i3 = i1;  // Ok
i3 = i2;  // Error
i3 = i4;  // Error

i4 = i1;  // Ok
i4 = i2;  // Ok
i4 = i3;  // Ok

interface Animal { animal: void }
interface Dog extends Animal { dog: void }
interface Cat extends Animal { cat: void }

interface Comparer1<T> {
    compare(a: T, b: T): number;
}

declare let animalComparer1: Comparer1<Animal>;
declare let dogComparer1: Comparer1<Dog>;

animalComparer1 = dogComparer1;  // Ok
dogComparer1 = animalComparer1;  // Ok

interface Comparer2<T> {
    compare: (a: T, b: T) => number;
}

declare let animalComparer2: Comparer2<Animal>;
declare let dogComparer2: Comparer2<Dog>;

animalComparer2 = dogComparer2;  // Error
dogComparer2 = animalComparer2;  // Ok

// Crate<T> is invariant in --strictFunctionTypes mode

interface Crate<T> {
    item: T;
    onSetItem: (item: T) => void;
}

declare let animalCrate: Crate<Animal>;
declare let dogCrate: Crate<Dog>;

// Errors below should elaborate the reason for invariance

animalCrate = dogCrate;  // Error
dogCrate = animalCrate;  // Error

// Verify that callback parameters are strictly checked

declare let fc1: (f: (x: Animal) => Animal) => void;
declare let fc2: (f: (x: Dog) => Dog) => void;
fc1 = fc2;  // Error
fc2 = fc1;  // Error

// Verify that callback parameters aren't loosely checked when types
// originate in method declarations

namespace n1 {
    class Foo {
        static f1(x: Animal): Animal { throw "wat"; }
        static f2(x: Dog): Animal { throw "wat"; };
    }
    declare let f1: (cb: typeof Foo.f1) => void;
    declare let f2: (cb: typeof Foo.f2) => void;
    f1 = f2;
    f2 = f1;  // Error
}

namespace n2 {
    type BivariantHack<Input, Output> = { foo(x: Input): Output }["foo"];
    declare let f1: (cb: BivariantHack<Animal, Animal>) => void;
    declare let f2: (cb: BivariantHack<Dog, Animal>) => void;
    f1 = f2;
    f2 = f1;  // Error
}