@@ -3,11 +3,11 @@ use oxc_ast::{
33 NONE ,
44 ast:: {
55 ArrayExpression , ArrayExpressionElement , ArrowFunctionExpression , Expression , Function ,
6- ObjectExpression , ObjectPropertyKind , TSLiteral , TSMethodSignatureKind , TSTupleElement ,
7- TSType , TSTypeOperatorOperator ,
6+ ObjectExpression , ObjectPropertyKind , PropertyKey , PropertyKind , TSLiteral ,
7+ TSMethodSignatureKind , TSTupleElement , TSType , TSTypeOperatorOperator ,
88 } ,
99} ;
10- use oxc_span:: { GetSpan , SPAN , Span } ;
10+ use oxc_span:: { ContentEq , GetSpan , SPAN , Span } ;
1111
1212use crate :: {
1313 IsolatedDeclarations ,
@@ -81,6 +81,12 @@ impl<'a> IsolatedDeclarations<'a> {
8181 expr : & ObjectExpression < ' a > ,
8282 is_const : bool ,
8383 ) -> TSType < ' a > {
84+ // The span of accessors that cannot infer the type.
85+ let mut accessor_spans = Vec :: new ( ) ;
86+ // One of setter or getter is inferred, then the PropertyKey will be added to it.
87+ // Use `Vec` rather than `HashSet` is because the `PropertyKey` is not satisfied with `Hash` trait,
88+ let mut accessor_inferred: Vec < PropertyKey < ' a > > = Vec :: new ( ) ;
89+
8490 let members =
8591 self . ast . vec_from_iter ( expr. properties . iter ( ) . filter_map ( |property| match property {
8692 ObjectPropertyKind :: ObjectProperty ( object) => {
@@ -111,26 +117,76 @@ impl<'a> IsolatedDeclarations<'a> {
111117 }
112118 }
113119
114- let type_annotation = if is_const {
115- self . transform_expression_to_ts_type ( & object. value )
116- } else {
117- self . infer_type_from_expression ( & object. value )
118- } ;
120+ let key = object. key . clone_in ( self . ast . allocator ) ;
119121
120- if type_annotation. is_none ( ) {
121- self . error ( inferred_type_of_expression ( object. value . span ( ) ) ) ;
122- return None ;
123- }
122+ let type_annotation = match object. kind {
123+ PropertyKind :: Get => {
124+ if accessor_inferred. iter ( ) . any ( |k| k. content_eq ( & key) ) {
125+ return None ;
126+ }
127+
128+ let Expression :: FunctionExpression ( function) = & object. value else {
129+ unreachable ! (
130+ "`object.kind` being `Get` guarantees that it is a function"
131+ ) ;
132+ } ;
133+
134+ let annotation = self . infer_function_return_type ( function) ;
135+ if annotation. is_none ( ) {
136+ accessor_spans. push ( ( key. clone_in ( self . ast . allocator ) , key. span ( ) ) ) ;
137+ return None ;
138+ }
139+
140+ accessor_inferred. push ( key. clone_in ( self . ast . allocator ) ) ;
141+ annotation
142+ }
143+ PropertyKind :: Set => {
144+ if accessor_inferred. iter ( ) . any ( |k| k. content_eq ( & key) ) {
145+ return None ;
146+ }
147+
148+ let Expression :: FunctionExpression ( function) = & object. value else {
149+ unreachable ! (
150+ "`object.kind` being `Set` guarantees that it is a function"
151+ ) ;
152+ } ;
153+ let annotation = function. params . items . first ( ) . and_then ( |param| {
154+ param. pattern . type_annotation . clone_in ( self . ast . allocator )
155+ } ) ;
156+ if annotation. is_none ( ) {
157+ accessor_spans
158+ . push ( ( key. clone_in ( self . ast . allocator ) , function. params . span ) ) ;
159+ return None ;
160+ }
161+
162+ accessor_inferred. push ( key. clone_in ( self . ast . allocator ) ) ;
163+ annotation
164+ }
165+ PropertyKind :: Init => {
166+ let type_annotation = if is_const {
167+ self . transform_expression_to_ts_type ( & object. value )
168+ } else {
169+ self . infer_type_from_expression ( & object. value )
170+ } ;
171+
172+ if type_annotation. is_none ( ) {
173+ self . error ( inferred_type_of_expression ( object. value . span ( ) ) ) ;
174+ return None ;
175+ }
176+
177+ type_annotation. map ( |type_annotation| {
178+ self . ast . alloc_ts_type_annotation ( SPAN , type_annotation)
179+ } )
180+ }
181+ } ;
124182
125183 let property_signature = self . ast . ts_signature_property_signature (
126184 object. span ,
127185 false ,
128186 false ,
129187 is_const,
130- object. key . clone_in ( self . ast . allocator ) ,
131- type_annotation. map ( |type_annotation| {
132- self . ast . ts_type_annotation ( SPAN , type_annotation)
133- } ) ,
188+ key,
189+ type_annotation,
134190 ) ;
135191 Some ( property_signature)
136192 }
@@ -139,6 +195,13 @@ impl<'a> IsolatedDeclarations<'a> {
139195 None
140196 }
141197 } ) ) ;
198+
199+ for ( key, span) in accessor_spans {
200+ if !accessor_inferred. iter ( ) . any ( |k| k. content_eq ( & key) ) {
201+ self . error ( inferred_type_of_expression ( span) ) ;
202+ }
203+ }
204+
142205 self . ast . ts_type_type_literal ( SPAN , members)
143206 }
144207
0 commit comments