swc-project/swc · error

flow type

Error message

flow type

What it means

swc_estree_ast models Babel class heritage type parameters as SuperTypeParams with two flavors: TS and Flow. In swc_estree_compat's typescript.rs conversion, the TS variant maps to TsTypeParamInstantiation, but SuperTypeParams::Flow hits unimplemented!("flow type") — Flow generics on an extends clause have no SWC representation. The surrounding code shows related gaps too (TSType conversion is a todo! for babel TS imports), so class-level type info from Babel is only partially convertible.

Solutions

  1. Detect Flow class heritage type params before conversion (superTypeParams.variant === "flow" or any Flow nodes) and skip/convert those files.
  2. Run flow-to-typescript first so heritage generics arrive as the TS variant, which converts fine.
  3. Strip Flow type annotations with Babel preset-flow before handing the AST to swcify (the stripped AST has no superTypeParams).
  4. Implement a lossy Flow -> TsTypeParamInstantiation mapping in crates/swc_estree_compat/src/swcify/typescript.rs.

Example fix

// before: `class App extends React.Component<Props> {}` parsed with ["flow"]
swcify(class_decl.super_type_params, ctx); // panics unimplemented!("flow type")

// after: branch on the flavor before converting
match super_type_params {
    SuperTypeParams::TS(v) => v.swcify(ctx),
    SuperTypeParams::Flow(_) => skip_or_convert_via_flow_to_ts(file),
}
Defensive patterns

Strategy: type-guard

Validate before calling

export function hasFlowSuperTypeParams(node) {
  if (!node || typeof node !== "object") return false;
  if (node.superTypeParams && node.superTypeParams.variant !== "TS") return true;
  return Object.values(node).some((v) =>
    Array.isArray(v) ? v.some(hasFlowSuperTypeParams) : hasFlowSuperTypeParams(v)
  );
}
if (hasFlowSuperTypeParams(babelAst)) routeToFlowConversion(file);

Type guard

function classHeritageIsConvertible(classNode) {
  const p = classNode.superTypeParams;
  return !p || p.variant === "TS";
}

Prevention

When it happens

Trigger: Calling swcify on a Babel AST parsed with the Flow plugin where any class declaration/expression has type parameters on its heritage clause, e.g. `class C extends React.Component<Props> {}` — the superTypeParams field carries the Flow variant and the match arm panics.

Common situations: Converting Flow React codebases whose components extend generic base classes; mixing Flow and TS fixtures through one Babel->SWC pipeline; migration tooling that assumes class shape converts identically across flavors.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/0c1c2ff69d9317c0. Report an issue: GitHub.

Appendix: source

Thrown at crates/swc_estree_compat/src/swcify/typescript.rs:109

            type_ann: self.type_annotation.swcify(ctx),
        }
    }
}

impl Swcify for TSType {
    type Output = Box<TsType>;

    fn swcify(self, _: &Context) -> Self::Output {
        todo!("swc currently does not support importing typescript module from babel")
    }
}

impl Swcify for SuperTypeParams {
    type Output = TsTypeParamInstantiation;

    fn swcify(self, ctx: &Context) -> Self::Output {
        match self {
            SuperTypeParams::Flow(_) => unimplemented!("flow type"),
            SuperTypeParams::TS(v) => v.swcify(ctx),
        }
    }
}

impl Swcify for Access {
    type Output = Accessibility;

    fn swcify(self, _: &Context) -> Self::Output {
        match self {
            Access::Public => Accessibility::Public,
            Access::Private => Accessibility::Private,
            Access::Protected => Accessibility::Protected,
        }
    }
}

impl Swcify for TSEntityName {

View on GitHub (pinned to 5176682b65)