Are
import type { Foo, Bar as Baz } from './'
and
type Foo = import('./').Foo
type Bar = import('./').Baz
equivalent?
Please be aware that the import()
in this context is not a dynamic import but import
types introduced in TypeScript 2.9. You can enter both examples into the TypeScript playground to verify that the syntax/types are valid.
I want to use import type
but also create declarations for TS < 3.8.
If the above assertion is true I could apply an AST transform to the emitted declaration files.
They are not equivalent, though they are often interchangeable in practice. There are two differences that can matter, depending on the context.
import type
makes a file a module. The TypeScript compiler determines whether a TypeScript file's top level scope is module-scoped or globally scoped (ie, whether the file is a module or a script) by the presence of any import
or export
declarations. import type
counts as an import declaration, so if it were the only import/export statement in the file, substituting a type alias for it would change the file from a module to a script. The practical implication of this is that if you have a file (usually adts file) that you need to be global, but want to reference types from a module, you're stuck using type Foo = import(...)
.
import type
can reference value and namespace meanings. When you declare a type alias with type Foo = import('./').Bar
, Foo
is purely a type, even if Bar
had both a type and a value meaning (eg class Bar {}
). You have completely left the value side of Bar
behind in this declaration. import type
actually references the full Bar
symbol and all its meanings, it just sets up a syntactic check that ensures you never use it in a position that would get emitted to JS (since the import statement will get erased in JS). This matters in a few places, easiest to show with an example:
import type { EventEmitter as EE1 } from "events";
type EE2 = import("events").EventEmitter;
// Ok, because `declare` means `Foo1` is not actually referenced
// in an emitting position.
declare class Derived1 extends EE1 {}
declare class Derived2 extends EE2 {}
// ^^^
// Error: 'EE2' only refers to a type, but is being used as a value here.
type EventEmitterCtor1 = typeof EE1; // Ok
type EventEmitterCtor2 = typeof EE2;
// ^^^
// Error: 'EE2' only refers to a type, but is being used as a value here.
const x = EE1;
// ^^^
// Error: 'EE1' cannot be used as a value because it was imported using 'import type'
const y = EE2;
// ^^^
// 'EE2' only refers to a type, but is being used as a value here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.