swc-project/swc · error

flow types

Error message

flow types

What it means

While converting a Babel/ESTree tagged template expression back to SWC, type parameters can only be TypeScript (mapped to TsTypeParamInstantiation). A Flow-flavored type parameter list (TaggedTemplateExprTypeParams::Flow) has no SWC representation — SWC's AST only models TS type args on tagged templates — so swcify panics with `unimplemented!("flow types")`.

Solutions

  1. Parse the source with the TypeScript syntax option (Babel typescript plugin / SWC parser) instead of Flow so type params come out as TS nodes
  2. Strip Flow type annotations with @babel/plugin-transform-flow-strip-types before swcify
  3. Skip Flow-typed nodes explicitly in a pre-conversion visitor

Example fix

// before
require('@babel/core').parseSync(code, { plugins: ['flow'] });

// after
require('@babel/core').parseSync(code, { plugins: ['typescript'] });
Defensive patterns

Strategy: validation

Validate before calling

// Node: assert the Babel parse used the TypeScript plugin, not flow
const ast = require('@babel/core').parseSync(code, {
  plugins: [['@babel/plugin-syntax-typescript', { isTSX: true }]],
});

Type guard

function isFlowTypedTaggedTemplate(node) {
  return node.type === 'TaggedTemplateExpression' && node.typeParameters?.type?.startsWith('Flow');
}

Prevention

When it happens

Trigger: Parsing source with Babel in Flow mode (e.g. `f<T>(\`...\`)`-style flow-typed tagged templates) and feeding the resulting AST into swcify instead of using a TypeScript parse.

Common situations: Toolchains that reuse a Babel parser configured for Flow (React Native legacy sources) and then try to convert the AST to SWC for further transforms.

Related errors


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

Appendix: source

Thrown at crates/swc_estree_compat/src/swcify/expr.rs:739

    type Output = TaggedTpl;

    fn swcify(self, ctx: &Context) -> Self::Output {
        TaggedTpl {
            span: ctx.span(&self.base),
            tag: self.tag.swcify(ctx),
            type_params: self.type_parameters.swcify(ctx).map(From::from),
            tpl: Box::new(self.quasi.swcify(ctx)),
            ..Default::default()
        }
    }
}

impl Swcify for TaggedTemplateExprTypeParams {
    type Output = TsTypeParamInstantiation;

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

impl Swcify for YieldExpression {
    type Output = YieldExpr;

    fn swcify(self, ctx: &Context) -> Self::Output {
        YieldExpr {
            span: ctx.span(&self.base),
            arg: self.argument.swcify(ctx),
            delegate: self.delegate,
        }
    }
}

impl Swcify for AwaitExpression {

View on GitHub (pinned to 5176682b65)