@@ -5,20 +5,36 @@ import * as VisitorUtils from './visitor-utils';
5
5
import * as VisitorKeyof from './visitor-keyof' ;
6
6
import * as VisitorIndexedAccess from './visitor-indexed-access' ;
7
7
8
- function visitTupleObjectType ( type : ts . TupleType , visitorContext : VisitorContext ) {
8
+ interface TypeCheckNameMode {
9
+ type : 'type-check' ;
10
+ superfluousPropertyCheck ?: boolean ;
11
+ }
12
+
13
+ interface KeyofNameMode {
14
+ type : 'keyof' ;
15
+ }
16
+
17
+ interface IndexedAccessNameMode {
18
+ type : 'indexed-access' ;
19
+ indexType : ts . Type ;
20
+ }
21
+
22
+ type NameMode = TypeCheckNameMode | KeyofNameMode | IndexedAccessNameMode ;
23
+
24
+ function visitTupleObjectType ( type : ts . TupleType , visitorContext : VisitorContext , mode : NameMode ) {
9
25
if ( type . typeArguments === undefined ) {
10
26
throw new Error ( 'Expected tuple type to have type arguments.' ) ;
11
27
}
12
- const itemNames = type . typeArguments . map ( ( type ) => visitType ( type , visitorContext ) ) ;
28
+ const itemNames = type . typeArguments . map ( ( type ) => visitType ( type , visitorContext , mode ) ) ;
13
29
return `st_${ itemNames . join ( '_' ) } _et` ;
14
30
}
15
31
16
- function visitArrayObjectType ( type : ts . ObjectType , visitorContext : VisitorContext ) {
32
+ function visitArrayObjectType ( type : ts . ObjectType , visitorContext : VisitorContext , mode : NameMode ) {
17
33
const numberIndexType = visitorContext . checker . getIndexTypeOfType ( type , ts . IndexKind . Number ) ;
18
34
if ( numberIndexType === undefined ) {
19
35
throw new Error ( 'Expected array ObjectType to have a number index type.' ) ;
20
36
}
21
- const numberIndexName = visitType ( numberIndexType , visitorContext ) ;
37
+ const numberIndexName = visitType ( numberIndexType , visitorContext , mode ) ;
22
38
return `sa_${ numberIndexName } _ea` ;
23
39
}
24
40
@@ -27,37 +43,37 @@ function visitRegularObjectType(type: ts.ObjectType) {
27
43
return `_${ id } ` ;
28
44
}
29
45
30
- function visitTypeReference ( type : ts . TypeReference , visitorContext : VisitorContext ) {
46
+ function visitTypeReference ( type : ts . TypeReference , visitorContext : VisitorContext , mode : NameMode ) {
31
47
const mapping : Map < ts . Type , ts . Type > = VisitorUtils . getTypeReferenceMapping ( type , visitorContext ) ;
32
48
const previousTypeReference = visitorContext . previousTypeReference ;
33
49
visitorContext . typeMapperStack . push ( mapping ) ;
34
50
visitorContext . previousTypeReference = type ;
35
- const result = visitType ( type . target , visitorContext ) ;
51
+ const result = visitType ( type . target , visitorContext , mode ) ;
36
52
visitorContext . previousTypeReference = previousTypeReference ;
37
53
visitorContext . typeMapperStack . pop ( ) ;
38
54
return result ;
39
55
}
40
56
41
- function visitTypeParameter ( type : ts . Type , visitorContext : VisitorContext ) {
57
+ function visitTypeParameter ( type : ts . Type , visitorContext : VisitorContext , mode : NameMode ) {
42
58
const mappedType = VisitorUtils . getResolvedTypeParameter ( type , visitorContext ) ;
43
59
if ( mappedType === undefined ) {
44
60
throw new Error ( 'Unbound type parameter, missing type node.' ) ;
45
61
}
46
- return visitType ( mappedType , visitorContext ) ;
62
+ return visitType ( mappedType , visitorContext , mode ) ;
47
63
}
48
64
49
- function visitObjectType ( type : ts . ObjectType , visitorContext : VisitorContext ) {
65
+ function visitObjectType ( type : ts . ObjectType , visitorContext : VisitorContext , mode : NameMode ) {
50
66
if ( tsutils . isTupleType ( type ) ) {
51
- return visitTupleObjectType ( type , visitorContext ) ;
67
+ return visitTupleObjectType ( type , visitorContext , mode ) ;
52
68
} else if ( visitorContext . checker . getIndexTypeOfType ( type , ts . IndexKind . Number ) ) {
53
- return visitArrayObjectType ( type , visitorContext ) ;
69
+ return visitArrayObjectType ( type , visitorContext , mode ) ;
54
70
} else {
55
71
return visitRegularObjectType ( type ) ;
56
72
}
57
73
}
58
74
59
- function visitUnionOrIntersectionType ( type : ts . UnionOrIntersectionType , visitorContext : VisitorContext ) {
60
- const names = type . types . map ( ( type ) => visitType ( type , visitorContext ) ) ;
75
+ function visitUnionOrIntersectionType ( type : ts . UnionOrIntersectionType , visitorContext : VisitorContext , mode : NameMode ) {
76
+ const names = type . types . map ( ( type ) => visitType ( type , visitorContext , mode ) ) ;
61
77
if ( tsutils . isIntersectionType ( type ) ) {
62
78
return `si_${ names . join ( '_' ) } _ei` ;
63
79
} else {
@@ -77,80 +93,61 @@ function visitIndexedAccessType(type: ts.IndexedAccessType, visitorContext: Visi
77
93
return VisitorIndexedAccess . visitType ( type . objectType , type . indexType , visitorContext ) ;
78
94
}
79
95
80
- export function visitType ( type : ts . Type , visitorContext : VisitorContext ) : string {
96
+ export function visitType ( type : ts . Type , visitorContext : VisitorContext , mode : NameMode ) : string {
97
+ let name : string ;
81
98
const id : string = ( type as unknown as { id : string } ) . id ;
82
99
if ( ( ts . TypeFlags . Any & type . flags ) !== 0 ) {
83
- return VisitorUtils . getAnyFunction ( visitorContext ) ;
100
+ name = VisitorUtils . getAnyFunction ( visitorContext ) ;
84
101
} else if ( ( ts . TypeFlags . Unknown & type . flags ) !== 0 ) {
85
- return VisitorUtils . getUnknownFunction ( visitorContext ) ;
102
+ name = VisitorUtils . getUnknownFunction ( visitorContext ) ;
86
103
} else if ( ( ts . TypeFlags . Never & type . flags ) !== 0 ) {
87
- return VisitorUtils . getNeverFunction ( visitorContext ) ;
104
+ name = VisitorUtils . getNeverFunction ( visitorContext ) ;
88
105
} else if ( ( ts . TypeFlags . Null & type . flags ) !== 0 ) {
89
- return VisitorUtils . getNullFunction ( visitorContext ) ;
106
+ name = VisitorUtils . getNullFunction ( visitorContext ) ;
90
107
} else if ( ( ts . TypeFlags . Undefined & type . flags ) !== 0 ) {
91
- return VisitorUtils . getUndefinedFunction ( visitorContext ) ;
108
+ name = VisitorUtils . getUndefinedFunction ( visitorContext ) ;
92
109
} else if ( ( ts . TypeFlags . Number & type . flags ) !== 0 ) {
93
- return VisitorUtils . getNumberFunction ( visitorContext ) ;
110
+ name = VisitorUtils . getNumberFunction ( visitorContext ) ;
94
111
} else if ( ( ts . TypeFlags . BigInt & type . flags ) !== 0 ) {
95
- return VisitorUtils . getBigintFunction ( visitorContext ) ;
112
+ name = VisitorUtils . getBigintFunction ( visitorContext ) ;
96
113
} else if ( ( ts . TypeFlags . Boolean & type . flags ) !== 0 ) {
97
- return VisitorUtils . getBooleanFunction ( visitorContext ) ;
114
+ name = VisitorUtils . getBooleanFunction ( visitorContext ) ;
98
115
} else if ( ( ts . TypeFlags . String & type . flags ) !== 0 ) {
99
- return VisitorUtils . getStringFunction ( visitorContext ) ;
116
+ name = VisitorUtils . getStringFunction ( visitorContext ) ;
100
117
} else if ( ( ts . TypeFlags . BooleanLiteral & type . flags ) !== 0 ) {
101
- return `_${ id } ` ;
118
+ name = `_${ id } ` ;
102
119
} else if ( tsutils . isTypeReference ( type ) && visitorContext . previousTypeReference !== type ) {
103
- return visitTypeReference ( type , visitorContext ) ;
120
+ name = visitTypeReference ( type , visitorContext , mode ) ;
104
121
} else if ( ( ts . TypeFlags . TypeParameter & type . flags ) !== 0 ) {
105
- return visitTypeParameter ( type , visitorContext ) ;
122
+ name = visitTypeParameter ( type , visitorContext , mode ) ;
106
123
} else if ( tsutils . isObjectType ( type ) ) {
107
- return visitObjectType ( type , visitorContext ) ;
124
+ name = visitObjectType ( type , visitorContext , mode ) ;
108
125
} else if ( tsutils . isLiteralType ( type ) ) {
109
- return `_${ id } ` ;
126
+ name = `_${ id } ` ;
110
127
} else if ( tsutils . isUnionOrIntersectionType ( type ) ) {
111
- return visitUnionOrIntersectionType ( type , visitorContext ) ;
128
+ name = visitUnionOrIntersectionType ( type , visitorContext , mode ) ;
112
129
} else if ( ( ts . TypeFlags . NonPrimitive & type . flags ) !== 0 ) {
113
- return `_${ id } ` ;
130
+ name = `_${ id } ` ;
114
131
} else if ( ( ts . TypeFlags . Index & type . flags ) !== 0 ) {
115
- return visitIndexType ( type , visitorContext ) ;
132
+ name = visitIndexType ( type , visitorContext ) ;
116
133
} else if ( tsutils . isIndexedAccessType ( type ) ) {
117
- return visitIndexedAccessType ( type , visitorContext ) ;
134
+ name = visitIndexedAccessType ( type , visitorContext ) ;
118
135
} else {
119
136
throw new Error ( 'Could not generate type-check; unsupported type with flags: ' + type . flags ) ;
120
137
}
121
- }
122
-
123
- interface TypeCheckNameMode {
124
- type : 'type-check' ;
125
- superfluousPropertyCheck ?: boolean ;
126
- }
127
-
128
- interface KeyofNameMode {
129
- type : 'keyof' ;
130
- }
131
-
132
- interface IndexedAccessNameMode {
133
- type : 'indexed-access' ;
134
- indexType : ts . Type ;
135
- }
136
-
137
- type NameMode = TypeCheckNameMode | KeyofNameMode | IndexedAccessNameMode ;
138
-
139
- export function getFullTypeName ( type : ts . Type , visitorContext : VisitorContext , mode : NameMode ) {
140
- let name = visitType ( type , visitorContext ) ;
141
138
if ( mode . type === 'keyof' ) {
142
139
name += '_keyof' ;
143
140
}
144
141
if ( mode . type === 'indexed-access' ) {
145
- const indexTypeName = getFullTypeName ( mode . indexType , visitorContext , { type : 'type-check' } ) ;
142
+ const indexTypeName = visitType ( mode . indexType , visitorContext , { type : 'type-check' } ) ;
146
143
name += `_ia__${ indexTypeName } ` ;
147
144
}
148
145
if ( mode . type === 'type-check' && ! ! mode . superfluousPropertyCheck ) {
149
146
name += '_s' ;
150
147
}
151
148
if ( tsutils . isTypeReference ( type ) && type . typeArguments !== undefined ) {
152
149
for ( const typeArgument of type . typeArguments ) {
153
- const resolvedType = VisitorUtils . getResolvedTypeParameter ( typeArgument , visitorContext ) ;
150
+ const resolvedType = VisitorUtils . getResolvedTypeParameter ( typeArgument , visitorContext ) || typeArgument ;
154
151
name += `_${ ( resolvedType as unknown as { id : string } ) . id } ` ;
155
152
}
156
153
}
0 commit comments