Skip to content

Wrong span for the as identifier in import/export { type as as X } specifiers #24536

Description

@arshad-yaseen

In a type-only specifier where the local name is literally as, the emitted Identifier node carries the span of the as keyword (the second as token) instead of the span of the identifier itself (the first as token). The identifier's name is correct, only start/end are wrong.

Repro (oxc-parser 0.140.0):

import { parseSync } from "oxc-parser";

const src = "export { type as as if };";
//           0123456789...
//                    ^type=9  ^as=14  ^as=17  ^if=20
const { program } = parseSync("x.ts", src, { sourceType: "module" });
console.log(JSON.stringify(program.body[0].specifiers[0], null, 2));

Actual:

{
  "type": "ExportSpecifier",
  "local": { "type": "Identifier", "name": "as", "start": 17, "end": 19 },
  "exported": { "type": "Identifier", "name": "if", "start": 20, "end": 22 },
  "exportKind": "type",
  "start": 9,
  "end": 22
}

local points at 17-19, which is the second as, the one serving as the rename keyword. That reading is internally inconsistent: it leaves no token between local (ends 19) and exported (starts 20) to act as the as keyword.

Expected: local should span 14-16 (the first as), with the second as (17-19) being the keyword. Babel and yuku both parse it this way: a type-only export specifier with local (as) at 14-16 and exported (if) at 20-22.

export { type as as if };
         ^^^^ type-only modifier
              ^^ local (14-16)
                 ^^ keyword (17-19)
                    ^^ exported (20-22)

AST explorer: oxc (actual) vs yuku (expected)

The import form has the same bug:

parseSync("x.ts", `import { type as as x } from "m";`, { sourceType: "module" });
// imported: { name: "as", start: 17, end: 19 }  (should be start: 14, end: 16)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions