swc-project/swc · error

{decl:?}

Error message

{decl:?}

What it means

While erasing TypeScript from module items, the transform handles expected VarDeclarator shapes (identifier names with/without initializers) and panics with `unreachable!("{decl:?}")` for anything else — e.g. a declarator whose name is an array/object binding pattern in a context the eraser does not support (such as ambient `declare` declarations).

Source

Thrown at crates/swc_ecma_transforms_typescript/src/transform.rs:1408

                        let expr = if exprs.len() == 1 {
                            exprs.pop().unwrap()
                        } else {
                            SeqExpr {
                                span: DUMMY_SP,
                                exprs,
                            }
                            .into()
                        };

                        stmts.push(
                            ExprStmt {
                                span: var_decl.span,
                                expr,
                            }
                            .into(),
                        );
                    }
                    decl => unreachable!("{decl:?}"),
                },
                ModuleItem::ModuleDecl(ModuleDecl::TsImportEquals(decl)) => {
                    match decl.module_ref {
                        TsModuleRef::TsEntityName(ts_entity_name) => {
                            let init = Self::ts_entity_name_to_expr(ts_entity_name);

                            // export impot foo = bar.baz
                            let stmt = if decl.is_export {
                                // Foo.foo = bar.baz
                                let left = id.clone().make_member(decl.id.clone().into());
                                let expr = init.make_assign_to(op!("="), left.into());

                                ExprStmt {
                                    span: decl.span,
                                    expr: expr.into(),
                                }
                                .into()
                            } else {

View on GitHub (pinned to 5176682b65)

Solutions

  1. Rewrite the ambient declaration to identifier form (`declare const a: number` instead of `declare const {a}: {a: number}`).
  2. Update swc_core — declarator coverage in the TS transform improves across releases.
  3. If valid tsc-accepted TS reproduces the panic on the latest version, file an swc issue with the snippet.

Example fix

// before: destructuring in an ambient declaration
export declare const { a, b }: { a: number; b: string };

// after: identifier declarators
export declare const a: number;
export declare const b: string;
Defensive patterns

Strategy: validation

Validate before calling

use swc_ecma_ast::{Pat, VarDeclarator};
fn declarators_supported(ds: &[VarDeclarator]) -> bool {
    ds.iter().all(|d| matches!(&d.name, Pat::Ident(_)))
}
// especially around ambient/`declare` VarDecls before the TS strip pass

Type guard

fn is_simple_declarator(d: &VarDeclarator) -> bool { matches!(&d.name, Pat::Ident(_)) }

Prevention

When it happens

Trigger: TS source or AST containing a variable declarator form the strip transform does not model — classically `declare const {a}: T` / `export declare let [a, b]: T` style ambient destructuring, or hand-built/foreign ASTs with unusual declarators, passed through swc_ecma_transforms_typescript.

Common situations: Ambient declaration files (.d.ts generation/stripping pipelines) using destructuring in declare contexts; codemods producing declarators with pattern names; older swc versions before broader declarator coverage.

Related errors


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