-
Notifications
You must be signed in to change notification settings - Fork 12.3k
/
excessPropertyCheckIntersectionWithRecursiveType.ts
106 lines (88 loc) · 2.13 KB
/
excessPropertyCheckIntersectionWithRecursiveType.ts
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
// @strict: true
// @noEmit: true
// repro from #44750
type Request = { l1: { l2: boolean } };
type Example<T> = { ex?: T | null };
type Schema1<T> = (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema1<T[P]> }; }) & Example<T>;
export const schemaObj1: Schema1<Request> = {
props: {
l1: {
props: {
l2: { type: 'boolean' },
invalid: false,
},
},
},
}
type Schema2<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: { [P in keyof T]: Schema2<T[P]> }; } & Example<T>);
export const schemaObj2: Schema2<Request> = {
props: {
l1: {
props: {
l2: { type: 'boolean' },
invalid: false,
},
},
},
}
type Schema3<T> = Example<T> & (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema3<T[P]> }; });
export const schemaObj3: Schema3<Request> = {
props: {
l1: {
props: {
l2: { type: 'boolean' },
invalid: false,
},
},
},
}
type Schema4<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: Example<T> & { [P in keyof T]: Schema4<T[P]> }; });
export const schemaObj4: Schema4<Request> = {
props: {
l1: {
props: {
l2: { type: 'boolean' },
invalid: false,
},
},
},
}
// repro from #40405
type Length<T extends any[]> = T["length"];
type Prepend<V, T extends any[]> = ((head: V, ...args: T) => void) extends (
...args: infer R
) => void
? R
: any;
type BuildTree<T, N extends number = -1, I extends any[] = []> = {
1: T;
0: T & { children: BuildTree<T, N, Prepend<any, I>>[] };
}[Length<I> extends N ? 1 : 0];
interface User {
name: string;
}
type GrandUser = BuildTree<User, 2>;
const grandUser: GrandUser = {
name: "Grand User",
children: [
{
name: "Son",
children: [
{
name: "Grand son",
children: [
{
name: "123",
children: [
{
name: "Some other name",
},
],
},
],
},
],
},
],
};
grandUser.children[0].children[0].children[0];