Closed tgrushka closed 3 weeks ago
Thanks for the in-depth description! I'm glad you're enjoying using oxc.
What you're experiencing is expected behavior. ImportOrExportKind
corresponds to the type
modifier on import/export statements, not the actual value of the symbol being imported/exported. I'll break it down:
import type
Consider the following files:
// foo.ts
export const a = 1
export interface B {}
// bar.ts
import { a, B } from './foo'
Parsing and static analysis of each file is done in isolation from other files. When parsing bar.ts
, we have no idea what kind of symbols a
and B
will be. I'll describe later what you can do if you need this information.
import type { RunOptions } from 'axe-core'
Here, the type
modifier applies to the entire declaration, not just a single specifier. If you put this code into our playground, you'll find that ImportOrExportType
on ImportDeclaration
is (correctly) a Type
, while ImportSpecifier
is a Value
.
import { type RunOptions } from 'axe-core'
Inverse of case two: the specifier is a Type
while the entire declaration is Value
. Playground link
Funny enough, cases 1 and two are meaningfully different. When compiled, case one gets completely removed, while case two gets compiled into
import {} from './foo'
This is because it is a value import declaration, and importing 'foo.ts' could have side effects.
Ok, now for a Tl;Dr of what you can do for point 1:
oxc-resolver
to find what file is being imported for each ImportSpecifier
ModuleRecord
to its SymbolTable
.SymbolTable
when doing stuff in bar.ts
Hope this helps!
Hi, great project! I'm working on a TypeScript to Rust types generator (why doesn't this exist yet? -- tried ts2rs crate but it's based on Pest & seems no longer maintained -- oxc seems much better for TypeScript -- really fast, don't have to write syntax rules, etc.).
Anyway, trying to figure out how to have an "entrypoint" .ts file in which I either import or export the types I want to convert, and found that an imported/exported type is detected as a
ImportOrExportKind::Value
rather than aImportOrExportKind::Type
unless very specific syntax is used:Case 1: examples/axe/axe-types.ts - FAILS TEST ❌
Case 2: examples/axe/axe-types.ts - FAILS TEST ❌
Case 3: examples/axe/axe-types.ts - PASSES TEST ✅
Maybe this is not a bug -- or less of a bug than I think it is -- because it seems you'd have to actually resolve the library to detect whether it is actually a
Type
orValue
. So maybe I need to resolve the import/export in my crate to check whether it is a type or not.In any case, if Case 1 is indeterminate, shouldn't Case 2 be able to pass, because
type
specifies everything in the curly braces -- or is this yet another TypeScript confusion? 🤔Example structure: Create
examples/axe
folder. Addpackage.json
andaxe-types.ts
(below) and runnpm install
. Addexamples/minimal.rs
file below and relevant dependencies toCargo.toml
.Note that in
axe-core/axe.d.ts
,RunOptions
is an interface:examples/axe/package.json
examples/minimal.rs