11//! Generator for TypeScript type definitions for all AST types.
22
3- use std:: borrow:: Cow ;
3+ use std:: { borrow:: Cow , fmt :: Write } ;
44
55use itertools:: Itertools ;
66
@@ -16,8 +16,6 @@ use crate::{
1616
1717use super :: { attr_positions, define_generator, AttrLocation , AttrPart , AttrPositions } ;
1818
19- const CUSTOM_TYPESCRIPT : & str = include_str ! ( "../../../../crates/oxc_ast/custom_types.d.ts" ) ;
20-
2119/// Generator for TypeScript type definitions.
2220pub struct TypescriptGenerator ;
2321
@@ -56,27 +54,49 @@ impl Generator for TypescriptGenerator {
5654
5755 let mut code = String :: new ( ) ;
5856 for type_def in & schema. types {
59- if ! type_def. generates_derive ( estree_derive_id) {
60- continue ;
57+ if type_def. generates_derive ( estree_derive_id) {
58+ generate_ts_type_def ( type_def , & mut code , schema ) ;
6159 }
60+ }
6261
63- let ts_type_def = match type_def {
64- TypeDef :: Struct ( struct_def) => generate_ts_type_def_for_struct ( struct_def, schema) ,
65- TypeDef :: Enum ( enum_def) => {
66- let ts_type_def = generate_ts_type_def_for_enum ( enum_def, schema) ;
67- let Some ( ts_type_def) = ts_type_def else { continue } ;
68- ts_type_def
69- }
70- _ => unreachable ! ( ) ,
71- } ;
62+ Output :: Javascript { path : TYPESCRIPT_DEFINITIONS_PATH . to_string ( ) , code }
63+ }
64+ }
7265
73- code. push_str ( & ts_type_def) ;
74- code. push_str ( "\n \n " ) ;
75- }
66+ /// Generate Typescript type definition for a struct or enum.
67+ ///
68+ /// Push type defs to `code`.
69+ fn generate_ts_type_def ( type_def : & TypeDef , code : & mut String , schema : & Schema ) {
70+ // Use custom TS def if provided via `#[estree(custom_ts_def = "...")]` attribute
71+ let custom_ts_def = match type_def {
72+ TypeDef :: Struct ( struct_def) => & struct_def. estree . custom_ts_def ,
73+ TypeDef :: Enum ( enum_def) => & enum_def. estree . custom_ts_def ,
74+ _ => unreachable ! ( ) ,
75+ } ;
7676
77- code. push_str ( CUSTOM_TYPESCRIPT ) ;
77+ if let Some ( custom_ts_def) = custom_ts_def {
78+ // Empty string means don't output any TS def at all for this type
79+ if !custom_ts_def. is_empty ( ) {
80+ write ! ( code, "export {custom_ts_def};\n \n " ) . unwrap ( ) ;
81+ }
82+ } else {
83+ // No custom definition. Generate one.
84+ let ts_def = match type_def {
85+ TypeDef :: Struct ( struct_def) => generate_ts_type_def_for_struct ( struct_def, schema) ,
86+ TypeDef :: Enum ( enum_def) => generate_ts_type_def_for_enum ( enum_def, schema) ,
87+ _ => unreachable ! ( ) ,
88+ } ;
89+ write ! ( code, "{ts_def};\n \n " ) . unwrap ( ) ;
90+ } ;
7891
79- Output :: Javascript { path : TYPESCRIPT_DEFINITIONS_PATH . to_string ( ) , code }
92+ // Add additional custom TS def if provided via `#[estree(add_ts_def = "...")]` attribute
93+ let add_ts_def = match type_def {
94+ TypeDef :: Struct ( struct_def) => & struct_def. estree . add_ts_def ,
95+ TypeDef :: Enum ( enum_def) => & enum_def. estree . add_ts_def ,
96+ _ => unreachable ! ( ) ,
97+ } ;
98+ if let Some ( add_ts_def) = add_ts_def {
99+ write ! ( code, "export {add_ts_def};\n \n " ) . unwrap ( ) ;
80100 }
81101}
82102
@@ -163,11 +183,7 @@ fn generate_ts_type_def_for_struct(struct_def: &StructDef, schema: &Schema) -> S
163183}
164184
165185/// Generate Typescript type definition for an enum.
166- fn generate_ts_type_def_for_enum ( enum_def : & EnumDef , schema : & Schema ) -> Option < String > {
167- if enum_def. estree . custom_ts_def {
168- return None ;
169- }
170-
186+ fn generate_ts_type_def_for_enum ( enum_def : & EnumDef , schema : & Schema ) -> String {
171187 let union = if enum_def. is_fieldless ( ) {
172188 enum_def
173189 . all_variants ( schema)
@@ -181,7 +197,7 @@ fn generate_ts_type_def_for_enum(enum_def: &EnumDef, schema: &Schema) -> Option<
181197 } ;
182198
183199 let enum_name = enum_def. name ( ) ;
184- Some ( format ! ( "export type {enum_name} = {union};" ) )
200+ format ! ( "export type {enum_name} = {union};" )
185201}
186202
187203/// Get TS type name for a type.
0 commit comments