From 7b711f096254e33f8dfda70efb164002a6724501 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Tue, 18 Mar 2025 07:46:55 +0000 Subject: [PATCH] fix(ast/estree): make TS-only fields optional in TS type defs (#9846) When the source type is JS/JSX, `parseSync` returns an AST without any of the TS fields present (properties not present at all, not just defined as `undefined` / `null`). So to make our type defs match that AST (and also the TS AST which *does* have these fields), these fields need to be optional. --- npm/oxc-types/types.d.ts | 92 ++++++++++---------- tasks/ast_tools/src/generators/typescript.rs | 9 +- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/npm/oxc-types/types.d.ts b/npm/oxc-types/types.d.ts index 347cdd15d110c..2194291169fb0 100644 --- a/npm/oxc-types/types.d.ts +++ b/npm/oxc-types/types.d.ts @@ -113,7 +113,7 @@ export interface TaggedTemplateExpression extends Span { type: 'TaggedTemplateExpression'; tag: Expression; quasi: TemplateLiteral; - typeArguments: TSTypeParameterInstantiation | null; + typeArguments?: TSTypeParameterInstantiation | null; } export interface TemplateElement extends Span { @@ -158,14 +158,14 @@ export interface CallExpression extends Span { callee: Expression; arguments: Array; optional: boolean; - typeArguments: TSTypeParameterInstantiation | null; + typeArguments?: TSTypeParameterInstantiation | null; } export interface NewExpression extends Span { type: 'NewExpression'; callee: Expression; arguments: Array; - typeArguments: TSTypeParameterInstantiation | null; + typeArguments?: TSTypeParameterInstantiation | null; } export interface MetaProperty extends Span { @@ -365,7 +365,7 @@ export interface VariableDeclaration extends Span { type: 'VariableDeclaration'; declarations: Array; kind: VariableDeclarationKind; - declare: boolean; + declare?: boolean; } export type VariableDeclarationKind = 'var' | 'let' | 'const' | 'using' | 'await using'; @@ -374,7 +374,7 @@ export interface VariableDeclarator extends Span { type: 'VariableDeclarator'; id: BindingPattern; init: Expression | null; - definite: boolean; + definite?: boolean; } export interface EmptyStatement extends Span { @@ -384,7 +384,7 @@ export interface EmptyStatement extends Span { export interface ExpressionStatement extends Span { type: 'ExpressionStatement'; expression: Expression; - directive: string | null; + directive?: string | null; } export interface IfStatement extends Span { @@ -496,8 +496,8 @@ export interface DebuggerStatement extends Span { export type BindingPattern = & ({ - typeAnnotation: TSTypeAnnotation | null; - optional: boolean; + typeAnnotation?: TSTypeAnnotation | null; + optional?: boolean; }) & (BindingIdentifier | ObjectPattern | ArrayPattern | AssignmentPattern); @@ -542,10 +542,10 @@ export interface Function extends Span { async: boolean; params: ParamPattern[]; body: FunctionBody | null; - declare: boolean; - typeParameters: TSTypeParameterDeclaration | null; - thisParam: TSThisParameter | null; - returnType: TSTypeAnnotation | null; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration | null; + thisParam?: TSThisParameter | null; + returnType?: TSTypeAnnotation | null; } export type ParamPattern = FormalParameter | FormalParameterRest; @@ -565,10 +565,10 @@ export interface FormalParameterRest extends Span { export type FormalParameter = & ({ - decorators: Array; - accessibility: TSAccessibility | null; - readonly: boolean; - override: boolean; + decorators?: Array; + accessibility?: TSAccessibility | null; + readonly?: boolean; + override?: boolean; }) & BindingPattern; @@ -585,8 +585,8 @@ export interface ArrowFunctionExpression extends Span { async: boolean; params: ParamPattern[]; body: FunctionBody | Expression; - typeParameters: TSTypeParameterDeclaration | null; - returnType: TSTypeAnnotation | null; + typeParameters?: TSTypeParameterDeclaration | null; + returnType?: TSTypeAnnotation | null; } export interface YieldExpression extends Span { @@ -600,12 +600,12 @@ export interface Class extends Span { id: BindingIdentifier | null; superClass: Expression | null; body: ClassBody; - decorators: Array; - typeParameters: TSTypeParameterDeclaration | null; - superTypeArguments: TSTypeParameterInstantiation | null; - implements: Array; - abstract: boolean; - declare: boolean; + decorators?: Array; + typeParameters?: TSTypeParameterDeclaration | null; + superTypeArguments?: TSTypeParameterInstantiation | null; + implements?: Array; + abstract?: boolean; + declare?: boolean; } export type ClassType = 'ClassDeclaration' | 'ClassExpression'; @@ -624,10 +624,10 @@ export interface MethodDefinition extends Span { key: PropertyKey; kind: MethodDefinitionKind; value: Function; - decorators: Array; - override: boolean; - optional: boolean; - accessibility: TSAccessibility | null; + decorators?: Array; + override?: boolean; + optional?: boolean; + accessibility?: TSAccessibility | null; } export type MethodDefinitionType = 'MethodDefinition' | 'TSAbstractMethodDefinition'; @@ -638,14 +638,14 @@ export interface PropertyDefinition extends Span { computed: boolean; key: PropertyKey; value: Expression | null; - decorators: Array; - declare: boolean; - override: boolean; - optional: boolean; - definite: boolean; - readonly: boolean; - typeAnnotation: TSTypeAnnotation | null; - accessibility: TSAccessibility | null; + decorators?: Array; + declare?: boolean; + override?: boolean; + optional?: boolean; + definite?: boolean; + readonly?: boolean; + typeAnnotation?: TSTypeAnnotation | null; + accessibility?: TSAccessibility | null; } export type PropertyDefinitionType = 'PropertyDefinition' | 'TSAbstractPropertyDefinition'; @@ -678,10 +678,10 @@ export interface AccessorProperty extends Span { value: Expression | null; computed: boolean; static: boolean; - decorators: Array; - definite: boolean; - typeAnnotation: TSTypeAnnotation | null; - accessibility: TSAccessibility | null; + decorators?: Array; + definite?: boolean; + typeAnnotation?: TSTypeAnnotation | null; + accessibility?: TSAccessibility | null; } export interface ImportExpression extends Span { @@ -695,7 +695,7 @@ export interface ImportDeclaration extends Span { specifiers: Array; source: StringLiteral; attributes: Array; - importKind: ImportOrExportKind; + importKind?: ImportOrExportKind; } export type ImportPhase = 'source' | 'defer'; @@ -706,7 +706,7 @@ export interface ImportSpecifier extends Span { type: 'ImportSpecifier'; imported: ModuleExportName; local: BindingIdentifier; - importKind: ImportOrExportKind; + importKind?: ImportOrExportKind; } export interface ImportDefaultSpecifier extends Span { @@ -733,7 +733,7 @@ export interface ExportNamedDeclaration extends Span { specifiers: Array; source: StringLiteral | null; attributes: Array; - exportKind: ImportOrExportKind; + exportKind?: ImportOrExportKind; } export interface ExportDefaultDeclaration extends Span { @@ -746,14 +746,14 @@ export interface ExportAllDeclaration extends Span { exported: ModuleExportName | null; source: StringLiteral; attributes: Array; - exportKind: ImportOrExportKind; + exportKind?: ImportOrExportKind; } export interface ExportSpecifier extends Span { type: 'ExportSpecifier'; local: ModuleExportName; exported: ModuleExportName; - exportKind: ImportOrExportKind; + exportKind?: ImportOrExportKind; } export type ExportDefaultDeclarationKind = Function | Class | TSInterfaceDeclaration | Expression; @@ -821,7 +821,7 @@ export interface JSXOpeningElement extends Span { attributes: Array; name: JSXElementName; selfClosing: boolean; - typeArguments: TSTypeParameterInstantiation | null; + typeArguments?: TSTypeParameterInstantiation | null; } export interface JSXClosingElement extends Span { diff --git a/tasks/ast_tools/src/generators/typescript.rs b/tasks/ast_tools/src/generators/typescript.rs index 32a52030902f2..0f246577b2597 100644 --- a/tasks/ast_tools/src/generators/typescript.rs +++ b/tasks/ast_tools/src/generators/typescript.rs @@ -270,7 +270,8 @@ fn generate_ts_type_def_for_struct_field_impl<'s>( } let field_camel_name = get_struct_field_name(field); - fields_str.push_str(&format!("\n\t{field_camel_name}: {field_type_name};")); + let question_mark = if field.estree.is_ts { "?" } else { "" }; + fields_str.push_str(&format!("\n\t{field_camel_name}{question_mark}: {field_type_name};")); } /// Generate Typescript type definition for an extra struct field @@ -281,10 +282,12 @@ fn generate_ts_type_def_for_added_struct_field( fields_str: &mut String, schema: &Schema, ) { - let Some(ts_type) = get_ts_type_for_converter(converter_name, schema) else { + let converter = schema.meta_by_name(converter_name); + let Some(ts_type) = converter.estree.ts_type.as_deref() else { panic!("No `ts_type` provided for ESTree converter `{converter_name}`"); }; - fields_str.push_str(&format!("\n\t{field_name}: {ts_type};")); + let question_mark = if converter.estree.is_ts { "?" } else { "" }; + fields_str.push_str(&format!("\n\t{field_name}{question_mark}: {ts_type};")); } /// Get the TS type definition for a converter.