This is a plugin for Acorn - a tiny, fast JavaScript parser, written completely in JavaScript.
It was created as an experimental alternative, faster TypeScript parser. It will help you to parse TypeScript using Acorn.
To get started, import the plugin and use Acorn's extension mechanism to register it. You have to enable options.locations while using @sveltejs/acorn-typescript.
import { Parser } from 'acorn';
import { tsPlugin } from '@sveltejs/acorn-typescript';
const node = Parser.extend(tsPlugin()).parse(
`
const a = 1
type A = number
export {
a,
type A as B
}
`,
{
sourceType: 'module',
ecmaVersion: 'latest',
locations: true
}
);If you want to enable parsing within a TypeScript ambient context, where certain syntax have different rules (like .d.ts files and inside declare module blocks):
import { Parser } from 'acorn';
import { tsPlugin } from '@sveltejs/acorn-typescript';
const node = Parser.extend(tsPlugin({ dts: true })).parse(
`
const a = 1
type A = number
export {
a,
type A as B
}
`,
{
sourceType: 'module',
ecmaVersion: 'latest',
locations: true
}
);This plugin produces a syntax tree; successful parsing does not mean that a program passes TypeScript's type checker. Imports and local declarations can share a name, because an imported type and a local value live in separate declaration spaces. For example, this is valid TypeScript:
import type { A } from './a';
const A = 1;This also applies to ordinary imports, not only type-only imports. The following is valid when
Config is exported from ./types as a type only:
import { Config } from './types';
const Config = { path: '/' };The parser does not know whether an imported name refers to a type or a value, so it also accepts
the same code when Config is exported as a value, even though TypeScript's checker then reports
Import declaration conflicts with local declaration of 'Config'.
Internal import aliases (import A = M) and type-only external aliases (import type A = require('a'))
can also share a name with local declarations. Ordinary external aliases (import A = require('a'))
still use lexical binding checks and cannot share a name with a const in the same scope. The parser
does not resolve the imported symbol or decide whether an accepted combination is semantically valid.
Use TypeScript's checker when your application needs those diagnostics.
An ordinary import and a type-only named import can also share a binding name. The parser still rejects malformed syntax and certain duplicate declarations in the same scope. For example, each of the following throws a parser error:
import { A } from './a';
import { A } from './b';const A = 1;
const A = 2;type A = number;
type A = string;These examples describe the scope of the import/local-name checks, rather than a complete list of the parser's syntax and declaration checks.
- Typescript normal syntax
- Support to parse TypeScript Decorators
- Support to parse JSX & TSX
Upgrading from v1? See the v1 to v2 migration guide, including the
ImportExpression.options AST change and Acorn configuration requirements.
We want to thank TyrealHu for his original work on this project. He maintained acorn-typescript until early 2024.