Skip to content

Commit d4a239c

Browse files
committed
Add tests
1 parent 3bf9f8e commit d4a239c

8 files changed

+583
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//// [inferenceDoesNotAddUndefinedOrNull.ts]
2+
interface NodeArray<T extends Node> extends ReadonlyArray<T> {}
3+
4+
interface Node {
5+
forEachChild<T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined;
6+
}
7+
8+
declare function toArray<T>(value: T | T[]): T[];
9+
declare function toArray<T>(value: T | readonly T[]): readonly T[];
10+
11+
function flatMapChildren<T>(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] {
12+
const result: T[] = [];
13+
node.forEachChild(child => {
14+
const value = cb(child);
15+
if (value !== undefined) {
16+
result.push(...toArray(value));
17+
}
18+
});
19+
return result;
20+
}
21+
22+
function flatMapChildren2<T>(node: Node, cb: (child: Node) => readonly T[] | T | null): readonly T[] {
23+
const result: T[] = [];
24+
node.forEachChild(child => {
25+
const value = cb(child);
26+
if (value !== null) {
27+
result.push(...toArray(value));
28+
}
29+
});
30+
return result;
31+
}
32+
33+
34+
//// [inferenceDoesNotAddUndefinedOrNull.js]
35+
"use strict";
36+
function flatMapChildren(node, cb) {
37+
var result = [];
38+
node.forEachChild(function (child) {
39+
var value = cb(child);
40+
if (value !== undefined) {
41+
result.push.apply(result, toArray(value));
42+
}
43+
});
44+
return result;
45+
}
46+
function flatMapChildren2(node, cb) {
47+
var result = [];
48+
node.forEachChild(function (child) {
49+
var value = cb(child);
50+
if (value !== null) {
51+
result.push.apply(result, toArray(value));
52+
}
53+
});
54+
return result;
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
=== tests/cases/compiler/inferenceDoesNotAddUndefinedOrNull.ts ===
2+
interface NodeArray<T extends Node> extends ReadonlyArray<T> {}
3+
>NodeArray : Symbol(NodeArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 0))
4+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 20))
5+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
6+
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
7+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 20))
8+
9+
interface Node {
10+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
11+
12+
forEachChild<T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined;
13+
>forEachChild : Symbol(Node.forEachChild, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 2, 16))
14+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 17))
15+
>cbNode : Symbol(cbNode, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 20))
16+
>node : Symbol(node, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 29))
17+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
18+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 17))
19+
>cbNodeArray : Symbol(cbNodeArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 58))
20+
>nodes : Symbol(nodes, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 74))
21+
>NodeArray : Symbol(NodeArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 0))
22+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
23+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 17))
24+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 3, 17))
25+
}
26+
27+
declare function toArray<T>(value: T | T[]): T[];
28+
>toArray : Symbol(toArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 4, 1), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 49))
29+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 25))
30+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 28))
31+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 25))
32+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 25))
33+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 25))
34+
35+
declare function toArray<T>(value: T | readonly T[]): readonly T[];
36+
>toArray : Symbol(toArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 4, 1), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 49))
37+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 25))
38+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 28))
39+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 25))
40+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 25))
41+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 25))
42+
43+
function flatMapChildren<T>(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] {
44+
>flatMapChildren : Symbol(flatMapChildren, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 7, 67))
45+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 25))
46+
>node : Symbol(node, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 28))
47+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
48+
>cb : Symbol(cb, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 39))
49+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 45))
50+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
51+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 25))
52+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 25))
53+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 25))
54+
55+
const result: T[] = [];
56+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 10, 9))
57+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 25))
58+
59+
node.forEachChild(child => {
60+
>node.forEachChild : Symbol(Node.forEachChild, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 2, 16))
61+
>node : Symbol(node, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 28))
62+
>forEachChild : Symbol(Node.forEachChild, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 2, 16))
63+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 11, 22))
64+
65+
const value = cb(child);
66+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 12, 13))
67+
>cb : Symbol(cb, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 9, 39))
68+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 11, 22))
69+
70+
if (value !== undefined) {
71+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 12, 13))
72+
>undefined : Symbol(undefined)
73+
74+
result.push(...toArray(value));
75+
>result.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
76+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 10, 9))
77+
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
78+
>toArray : Symbol(toArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 4, 1), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 49))
79+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 12, 13))
80+
}
81+
});
82+
return result;
83+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 10, 9))
84+
}
85+
86+
function flatMapChildren2<T>(node: Node, cb: (child: Node) => readonly T[] | T | null): readonly T[] {
87+
>flatMapChildren2 : Symbol(flatMapChildren2, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 18, 1))
88+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 26))
89+
>node : Symbol(node, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 29))
90+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
91+
>cb : Symbol(cb, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 40))
92+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 46))
93+
>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 0, 63))
94+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 26))
95+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 26))
96+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 26))
97+
98+
const result: T[] = [];
99+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 21, 9))
100+
>T : Symbol(T, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 26))
101+
102+
node.forEachChild(child => {
103+
>node.forEachChild : Symbol(Node.forEachChild, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 2, 16))
104+
>node : Symbol(node, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 29))
105+
>forEachChild : Symbol(Node.forEachChild, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 2, 16))
106+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 22, 22))
107+
108+
const value = cb(child);
109+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 23, 13))
110+
>cb : Symbol(cb, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 20, 40))
111+
>child : Symbol(child, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 22, 22))
112+
113+
if (value !== null) {
114+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 23, 13))
115+
116+
result.push(...toArray(value));
117+
>result.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
118+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 21, 9))
119+
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
120+
>toArray : Symbol(toArray, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 4, 1), Decl(inferenceDoesNotAddUndefinedOrNull.ts, 6, 49))
121+
>value : Symbol(value, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 23, 13))
122+
}
123+
});
124+
return result;
125+
>result : Symbol(result, Decl(inferenceDoesNotAddUndefinedOrNull.ts, 21, 9))
126+
}
127+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
=== tests/cases/compiler/inferenceDoesNotAddUndefinedOrNull.ts ===
2+
interface NodeArray<T extends Node> extends ReadonlyArray<T> {}
3+
4+
interface Node {
5+
forEachChild<T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined;
6+
>forEachChild : <T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: ((nodes: NodeArray<Node>) => T | undefined) | undefined) => T | undefined
7+
>cbNode : (node: Node) => T | undefined
8+
>node : Node
9+
>cbNodeArray : ((nodes: NodeArray<Node>) => T | undefined) | undefined
10+
>nodes : NodeArray<Node>
11+
}
12+
13+
declare function toArray<T>(value: T | T[]): T[];
14+
>toArray : { <T>(value: T | T[]): T[]; <T>(value: T | readonly T[]): readonly T[]; }
15+
>value : T | T[]
16+
17+
declare function toArray<T>(value: T | readonly T[]): readonly T[];
18+
>toArray : { <T>(value: T | T[]): T[]; <T>(value: T | readonly T[]): readonly T[]; }
19+
>value : T | readonly T[]
20+
21+
function flatMapChildren<T>(node: Node, cb: (child: Node) => readonly T[] | T | undefined): readonly T[] {
22+
>flatMapChildren : <T>(node: Node, cb: (child: Node) => readonly T[] | T | undefined) => readonly T[]
23+
>node : Node
24+
>cb : (child: Node) => readonly T[] | T | undefined
25+
>child : Node
26+
27+
const result: T[] = [];
28+
>result : T[]
29+
>[] : never[]
30+
31+
node.forEachChild(child => {
32+
>node.forEachChild(child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } }) : void | undefined
33+
>node.forEachChild : <T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: ((nodes: NodeArray<Node>) => T | undefined) | undefined) => T | undefined
34+
>node : Node
35+
>forEachChild : <T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: ((nodes: NodeArray<Node>) => T | undefined) | undefined) => T | undefined
36+
>child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } } : (child: Node) => void
37+
>child : Node
38+
39+
const value = cb(child);
40+
>value : T | readonly T[] | undefined
41+
>cb(child) : T | readonly T[] | undefined
42+
>cb : (child: Node) => T | readonly T[] | undefined
43+
>child : Node
44+
45+
if (value !== undefined) {
46+
>value !== undefined : boolean
47+
>value : T | readonly T[] | undefined
48+
>undefined : undefined
49+
50+
result.push(...toArray(value));
51+
>result.push(...toArray(value)) : number
52+
>result.push : (...items: T[]) => number
53+
>result : T[]
54+
>push : (...items: T[]) => number
55+
>...toArray(value) : T
56+
>toArray(value) : readonly T[]
57+
>toArray : { <T>(value: T | T[]): T[]; <T>(value: T | readonly T[]): readonly T[]; }
58+
>value : readonly T[] | (T & ({} | null))
59+
}
60+
});
61+
return result;
62+
>result : T[]
63+
}
64+
65+
function flatMapChildren2<T>(node: Node, cb: (child: Node) => readonly T[] | T | null): readonly T[] {
66+
>flatMapChildren2 : <T>(node: Node, cb: (child: Node) => readonly T[] | T | null) => readonly T[]
67+
>node : Node
68+
>cb : (child: Node) => readonly T[] | T | null
69+
>child : Node
70+
>null : null
71+
72+
const result: T[] = [];
73+
>result : T[]
74+
>[] : never[]
75+
76+
node.forEachChild(child => {
77+
>node.forEachChild(child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } }) : void | undefined
78+
>node.forEachChild : <T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: ((nodes: NodeArray<Node>) => T | undefined) | undefined) => T | undefined
79+
>node : Node
80+
>forEachChild : <T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: ((nodes: NodeArray<Node>) => T | undefined) | undefined) => T | undefined
81+
>child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } } : (child: Node) => void
82+
>child : Node
83+
84+
const value = cb(child);
85+
>value : T | readonly T[] | null
86+
>cb(child) : T | readonly T[] | null
87+
>cb : (child: Node) => T | readonly T[] | null
88+
>child : Node
89+
90+
if (value !== null) {
91+
>value !== null : boolean
92+
>value : T | readonly T[] | null
93+
>null : null
94+
95+
result.push(...toArray(value));
96+
>result.push(...toArray(value)) : number
97+
>result.push : (...items: T[]) => number
98+
>result : T[]
99+
>push : (...items: T[]) => number
100+
>...toArray(value) : T
101+
>toArray(value) : readonly T[]
102+
>toArray : { <T>(value: T | T[]): T[]; <T>(value: T | readonly T[]): readonly T[]; }
103+
>value : readonly T[] | (T & ({} | undefined))
104+
}
105+
});
106+
return result;
107+
>result : T[]
108+
}
109+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [inferenceOfNullableObjectTypesWithCommonBase.ts]
2+
function equal<T>(a: T, b: T) { }
3+
4+
let v = null!;
5+
6+
// Object types with common base types
7+
8+
type B = { foo: string }
9+
type D = { foo: string; bar: number }
10+
11+
equal(v as B, v as undefined | D)
12+
equal(v as undefined | D, v as B)
13+
14+
equal<undefined | B>(v as B, v as undefined | D)
15+
equal<undefined | B>(v as undefined | D, v as B)
16+
17+
equal(v as B, v as undefined)
18+
equal(v as undefined, v as B)
19+
20+
equal(v as B, v as D)
21+
equal(v as D, v as B)
22+
23+
equal(v as B, v as B | undefined)
24+
equal(v as B | undefined, v as B)
25+
26+
27+
//// [inferenceOfNullableObjectTypesWithCommonBase.js]
28+
"use strict";
29+
function equal(a, b) { }
30+
var v = null;
31+
equal(v, v);
32+
equal(v, v);
33+
equal(v, v);
34+
equal(v, v);
35+
equal(v, v);
36+
equal(v, v);
37+
equal(v, v);
38+
equal(v, v);
39+
equal(v, v);
40+
equal(v, v);

0 commit comments

Comments
 (0)