diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index ca4a2a27c6ee1..84b4329df403d 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1899,6 +1899,7 @@ pub struct Class<'a> { /// // ^^^ /// ``` #[ts] + #[estree(via = ClassImplements)] pub implements: Option>>, pub body: Box<'a, ClassBody<'a>>, /// Whether the class is abstract diff --git a/crates/oxc_ast/src/generated/derive_estree.rs b/crates/oxc_ast/src/generated/derive_estree.rs index 3333b22589d98..b83267ee7c0d1 100644 --- a/crates/oxc_ast/src/generated/derive_estree.rs +++ b/crates/oxc_ast/src/generated/derive_estree.rs @@ -1450,7 +1450,7 @@ impl ESTree for Class<'_> { state.serialize_ts_field("decorators", &self.decorators); state.serialize_ts_field("typeParameters", &self.type_parameters); state.serialize_ts_field("superTypeArguments", &self.super_type_arguments); - state.serialize_ts_field("implements", &self.implements); + state.serialize_ts_field("implements", &crate::serialize::ClassImplements(self)); state.serialize_ts_field("abstract", &self.r#abstract); state.serialize_ts_field("declare", &self.declare); state.end(); diff --git a/crates/oxc_ast/src/serialize.rs b/crates/oxc_ast/src/serialize.rs index 47632e04162b9..a62d53384a06d 100644 --- a/crates/oxc_ast/src/serialize.rs +++ b/crates/oxc_ast/src/serialize.rs @@ -505,6 +505,26 @@ impl ESTree for ExportAllDeclarationWithClause<'_, '_> { } } +#[ast_meta] +#[estree( + ts_type = "Array", + raw_deser = " + const classImplements = DESER[Option>](POS_OFFSET.implements); + classImplements === null ? [] : classImplements + " +)] +pub struct ClassImplements<'a, 'b>(pub &'b Class<'a>); + +impl ESTree for ClassImplements<'_, '_> { + fn serialize(&self, serializer: S) { + if let Some(implements) = &self.0.implements { + implements.serialize(serializer); + } else { + [(); 0].serialize(serializer); + } + } +} + // -------------------- // JSX // -------------------- diff --git a/napi/parser/deserialize-ts.js b/napi/parser/deserialize-ts.js index 4d99d18e80384..3e213b0683cfd 100644 --- a/napi/parser/deserialize-ts.js +++ b/napi/parser/deserialize-ts.js @@ -844,6 +844,7 @@ function deserializeYieldExpression(pos) { } function deserializeClass(pos) { + const classImplements = deserializeOptionVecTSClassImplements(pos + 112); return { type: deserializeClassType(pos + 8), start: deserializeU32(pos), @@ -854,7 +855,7 @@ function deserializeClass(pos) { decorators: deserializeVecDecorator(pos + 16), typeParameters: deserializeOptionBoxTSTypeParameterDeclaration(pos + 80), superTypeArguments: deserializeOptionBoxTSTypeParameterInstantiation(pos + 104), - implements: deserializeOptionVecTSClassImplements(pos + 112), + implements: classImplements === null ? [] : classImplements, abstract: deserializeBool(pos + 152), declare: deserializeBool(pos + 153), }; diff --git a/npm/oxc-types/types.d.ts b/npm/oxc-types/types.d.ts index 65ca29fa7cf92..4e101e9d744de 100644 --- a/npm/oxc-types/types.d.ts +++ b/npm/oxc-types/types.d.ts @@ -602,7 +602,7 @@ export interface Class extends Span { decorators: Array; typeParameters: TSTypeParameterDeclaration | null; superTypeArguments: TSTypeParameterInstantiation | null; - implements: Array | null; + implements: Array; abstract: boolean; declare: boolean; }