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
- Detect Flow class heritage type params before conversion (superTypeParams.variant === "flow" or any Flow nodes) and skip/convert those files.
- Run flow-to-typescript first so heritage generics arrive as the TS variant, which converts fine.
- Strip Flow type annotations with Babel preset-flow before handing the AST to swcify (the stripped AST has no superTypeParams).
- 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
- For Flow sources, strip types with preset-flow before conversion so heritage type params disappear
- Unit-test your converter against both a Flow and a TS generic-class fixture so flavor regressions surface early
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)