Import Export
O JavaScript adicionou import/export à linguagem em 2016
e TypeScript tem suporte completo para esse estilo de
conexão entre arquivos e entre modulos externos.
O TypeScript expande essa sintaxe ao permitir que tipos
sejam importados e exportados junto com o código.
Vamos ver o import de código de um módulo.
// Aqui importamos um conjunto de import nomeados
("named imports") de um módulo do Node chamado danger.
Apesar de haver mais do que quatro imports,
esses são os únicos que nós escolhemos importar.
Nomeando especificamente quais imports você precisa,
permite que ferramentas tenham a habilidade de remover
código não utilizado em seu applicativo, e ajuda você a
entender o que está sendo utilizado nessa arquivo em particular.
Nesse caso: danger, message e warn são imports de JavaScript
enquanto que DangerDSLType é uma interface.
O TypeScript permite que engenheiros documentem seus códigos usando
JSDoc, e a documentação é importada também. Por exemplo, se você
passar o mouse sobre diferentes partes abaixo, você verá
explicações sobre o que elas são.
import { danger, message, warn, DangerDSLType } from "danger";
// Se você quiser saber como criar essas anotações de documentação
leia o exemplo:jsdoc-support
Outro modo de importar código é através do export
padrão de um módulo. Um exemplo disso é o módulo debug, o qual
expõe uma função que cria uma função de log.
danger.git.modified_files;
// Por conta das exports padrões ("default exports") não terem um nome,
elas podem ser delicadas de se trabalhar junto com ferramentas de análise estática
como o suporte a refactoração em TypeScript, mas elas têm o seu próprio uso.
Por haver uma longa história sobre import/export de código
em JavaScript, existe uma parte confusa sobre o export padrão:
alguns módulos exportados tem documentação que sugere que você possa
escrever um import como este:
import debug from "debug";
const log = debug("playground");
log("Código começou a rodar");
// Entretanto, isto apresenta uma erro. E então você encontra no
Stack Overflow uma recomendação de import como esta:
import req from "request";
// E este funciona. Por que? Nós vamos voltar a isso no final
da nossa sessão sobre export.
Para realizar um import, você precisa fazer um export.
O modo moderno de escrever exports é através da palavra-chave export
import * as req from "request";
// Isso poderia ter sido importado em outro arquivo usando:
import { numeroDeAdesivos } from "./caminho/para/o/arquivo"
Vocé pode ter tantas importações em um arquivo quantas forem necessárias.
Já um export padrão é bem parecido com isso.
/** O número atual de adesivos que sobraram no rolo */
export const numeroDeAdesivos = 11;
// Isto poderia ser importado em outro arquivo usando:
import pegueAdesivos from "./caminho/para/o/arquivo"
O nome é decidido pelo módulo que está realizando o import.
Estes não são os únicos tipos de import, apenas os
mais comuns em código moderno. Há um tópico bem abrangente
sobre todos os modos que um código pode cruzar as fronteiras
de um módulo no manual:
https://www.typescriptlang.org/docs/handbook/modules.html
Entretanto, para tentar responder a última questão. Se você
observar o código JavaScript desse exemplo, você verá isto:
var geradorDeAdesivos = function () { };
exports.default = geradorDeAdesivos;
Isso define a propriedade padrão ("default") no objeto exports como
geradorDeAdesivos. Existe código que define o exports como uma
função ao invés de um objeto.
O TypeScript optou por utilizar a especificação ECMAScript
sobre como lidar com esses casos, que é criar um erro.
Entretanto, existe uma configuração do compilador que lida
automaticamente com esses casos para você, que é a esModuleInterop.
Se você ativar ela nesse exemplo, você verá que o erro desaparece.
/** Cria um adesivo para você */
const geradorDeAdesivos = () => {};
export default geradorDeAdesivos;