Búsqueda de sitios web

typescript - ¿Es `import type` equivalente a `import()`?


Son

import type { Foo, Bar as Baz } from './'

y

type Foo = import('./').Foo
type Bar = import('./').Baz

¿equivalente?

Tenga en cuenta que el import() en este contexto no es una importación dinámica, sino los tipos de import introducidos en TypeScript 2.9. Puede ingresar ambos ejemplos en el playground de TypeScript para verificar que la sintaxis/los tipos son válidos.

Quiero usar import type pero también crear declaraciones para TS < 3.8.

Si la afirmación anterior es cierta, podría aplicar una transformación AST a los archivos de declaración emitidos.

Respuesta #1

No son equivalentes, aunque a menudo se pueden intercambiar en la práctica. Hay dos diferencias que pueden importar, dependiendo del contexto.

import type hace que un archivo sea un módulo.

El compilador de TypeScript determina si el alcance a nivel superior de un archivo TypeScript tiene alcance de módulo o alcance global (es decir, si el archivo es un módulo o un script) por la presencia de cualquier declaración import o export. import type cuenta como una declaración de importación, por lo que si fuera la única declaración de importación/exportación en el archivo, sustituirla por un alias de tipo cambiaría el archivo de un módulo a un script. La implicación práctica de esto es que si tienes un archivo (usualmente un archivo .d.ts) que necesitas que sea global, pero quieres referenciar tipos desde un módulo, estás obligado a usar type Foo=import(...).

import type puede referirse a los significados de valor y espacio de nombres.

Cuando declaras un alias de tipo con type Foo=import('./').Bar, Foo es puramente un tipo, incluso si Bar tenía tanto un significado de tipo como de valor (por ejemplo, class Bar {}). Has dejado completamente el lado de valor de Bar fuera de esta declaración. import type en realidad hace referencia al símbolo completo Bar y a todos sus significados, solo que establece una verificación sintáctica que asegura que nunca lo uses en una posición que se emitiría a JS (ya que la declaración de importación se borrará en JS). Esto importa en algunos lugares, y es más fácil de mostrar con un ejemplo:

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.

(Enlace al área de juegos)

Artículos relacionados