@@ -108,7 +108,11 @@ impl<'a> IsolatedDeclarations<'a> {
108
108
}
109
109
}
110
110
111
- let type_annotation = self . infer_type_from_expression ( & object. value ) ;
111
+ let type_annotation = if is_const {
112
+ self . transform_expression_to_ts_type ( & object. value )
113
+ } else {
114
+ self . infer_type_from_expression ( & object. value )
115
+ } ;
112
116
113
117
if type_annotation. is_none ( ) {
114
118
self . error ( inferred_type_of_expression ( object. value . span ( ) ) ) ;
@@ -142,17 +146,19 @@ impl<'a> IsolatedDeclarations<'a> {
142
146
is_const : bool ,
143
147
) -> TSType < ' a > {
144
148
let element_types =
145
- self . ast . new_vec_from_iter ( expr. elements . iter ( ) . filter_map ( |element| match element {
146
- ArrayExpressionElement :: SpreadElement ( spread) => {
147
- self . error ( arrays_with_spread_elements ( spread. span ) ) ;
148
- None
149
- }
150
- ArrayExpressionElement :: Elision ( elision) => {
151
- Some ( TSTupleElement :: from ( self . ast . ts_undefined_keyword ( elision. span ) ) )
149
+ self . ast . new_vec_from_iter ( expr. elements . iter ( ) . filter_map ( |element| {
150
+ match element {
151
+ ArrayExpressionElement :: SpreadElement ( spread) => {
152
+ self . error ( arrays_with_spread_elements ( spread. span ) ) ;
153
+ None
154
+ }
155
+ ArrayExpressionElement :: Elision ( elision) => {
156
+ Some ( TSTupleElement :: from ( self . ast . ts_undefined_keyword ( elision. span ) ) )
157
+ }
158
+ _ => self
159
+ . transform_expression_to_ts_type ( element. to_expression ( ) )
160
+ . map ( TSTupleElement :: from) ,
152
161
}
153
- _ => Some ( TSTupleElement :: from (
154
- self . transform_expression_to_ts_type ( element. to_expression ( ) ) ,
155
- ) ) ,
156
162
} ) ) ;
157
163
158
164
let ts_type = self . ast . ts_tuple_type ( SPAN , element_types) ;
@@ -164,36 +170,58 @@ impl<'a> IsolatedDeclarations<'a> {
164
170
}
165
171
166
172
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions
167
- pub fn transform_expression_to_ts_type ( & self , expr : & Expression < ' a > ) -> TSType < ' a > {
173
+ pub fn transform_expression_to_ts_type ( & self , expr : & Expression < ' a > ) -> Option < TSType < ' a > > {
168
174
match expr {
169
175
Expression :: BooleanLiteral ( lit) => {
170
- self . ast . ts_literal_type ( SPAN , TSLiteral :: BooleanLiteral ( self . ast . copy ( lit) ) )
176
+ Some ( self . ast . ts_literal_type ( SPAN , TSLiteral :: BooleanLiteral ( self . ast . copy ( lit) ) ) )
171
177
}
172
178
Expression :: NumericLiteral ( lit) => {
173
- self . ast . ts_literal_type ( SPAN , TSLiteral :: NumericLiteral ( self . ast . copy ( lit) ) )
179
+ Some ( self . ast . ts_literal_type ( SPAN , TSLiteral :: NumericLiteral ( self . ast . copy ( lit) ) ) )
174
180
}
175
181
Expression :: BigintLiteral ( lit) => {
176
- self . ast . ts_literal_type ( SPAN , TSLiteral :: BigintLiteral ( self . ast . copy ( lit) ) )
182
+ Some ( self . ast . ts_literal_type ( SPAN , TSLiteral :: BigintLiteral ( self . ast . copy ( lit) ) ) )
177
183
}
178
184
Expression :: StringLiteral ( lit) => {
179
- self . ast . ts_literal_type ( SPAN , TSLiteral :: StringLiteral ( self . ast . copy ( lit) ) )
185
+ Some ( self . ast . ts_literal_type ( SPAN , TSLiteral :: StringLiteral ( self . ast . copy ( lit) ) ) )
180
186
}
187
+ Expression :: NullLiteral ( lit) => Some ( self . ast . ts_null_keyword ( lit. span ) ) ,
188
+ Expression :: Identifier ( ident) => match ident. name . as_str ( ) {
189
+ "undefined" => Some ( self . ast . ts_undefined_keyword ( ident. span ) ) ,
190
+ _ => None ,
191
+ } ,
181
192
Expression :: TemplateLiteral ( lit) => {
182
- self . ast . ts_literal_type ( SPAN , TSLiteral :: TemplateLiteral ( self . ast . copy ( lit) ) )
183
- }
184
- Expression :: UnaryExpression ( expr) => {
185
- self . ast . ts_literal_type ( SPAN , TSLiteral :: UnaryExpression ( self . ast . copy ( expr) ) )
193
+ if lit. expressions . is_empty ( ) {
194
+ lit. quasis . first ( ) . map ( |item| {
195
+ self . ast . ts_literal_type (
196
+ SPAN ,
197
+ TSLiteral :: StringLiteral ( self . ast . alloc ( self . ast . string_literal (
198
+ lit. span ,
199
+ if let Some ( cooked) = & item. value . cooked {
200
+ cooked
201
+ } else {
202
+ & item. value . raw
203
+ } ,
204
+ ) ) ) ,
205
+ )
206
+ } )
207
+ } else {
208
+ None
209
+ }
186
210
}
211
+ Expression :: UnaryExpression ( expr) => Some (
212
+ self . ast . ts_literal_type ( SPAN , TSLiteral :: UnaryExpression ( self . ast . copy ( expr) ) ) ,
213
+ ) ,
187
214
Expression :: ArrayExpression ( expr) => {
188
- self . transform_array_expression_to_ts_type ( expr, true )
215
+ Some ( self . transform_array_expression_to_ts_type ( expr, true ) )
189
216
}
190
217
Expression :: ObjectExpression ( expr) => {
191
- // { readonly a: number }
192
- self . transform_object_expression_to_ts_type ( expr, true )
218
+ Some ( self . transform_object_expression_to_ts_type ( expr, true ) )
193
219
}
194
- _ => {
195
- unreachable ! ( )
220
+ Expression :: FunctionExpression ( func) => self . transform_function_to_ts_type ( func) ,
221
+ Expression :: ArrowFunctionExpression ( func) => {
222
+ self . transform_arrow_function_to_ts_type ( func)
196
223
}
224
+ _ => None ,
197
225
}
198
226
}
199
227
}
0 commit comments