javascript - exportación por defecto en Typescript
Acabo de empezar a mirar Typescript y tengo un problema al jugar un poco.
Quiero escribir una biblioteca para gestionar una estructura de árbol general y solo estoy haciendo algunas pruebas muy básicas para ver cómo funciona TS.
Inicio de la configuración simple con 3 archivos:
- GForest.ts
- GTree.ts
- GNode.ts
Actualmente, GForest.ts:
import * as Immutable from "immutable";
import GTree from "./GTree";
export default class Forest{
public static createTree(){
let tree = new GTree();
}
}
GTree.ts:
export default class GTree{
constructor(){
console.log("Tree constructed");
}
public static createNode(){
}
}
Creé un archivo test.js simple para llamar a la biblioteca (TS compilado a ES5):
var GForest = require("./build/GForest");
console.log(GForest);
Al correr
> node test
La salida es:
No entiendo por qué el resultado es:
{ default: { [Function: Forest] createTree: [Function] } }
¿Por qué hay un objeto con default como clave y cómo puedo cambiar esto para lograr el comportamiento deseado?
Debido a esto, no puedo simplemente llamar:
GForest.createTree();
(Quiero exponer la creación de un árbol a través de una fábrica estática) ¿Alguna ayuda?
Respuesta #1
Usa la exportación default de ES6
Cito el artículo ES6 In Depth: Modules de Mozilla:
Si deseas que tu propio módulo ES6 tenga una exportación predeterminada, eso es fácil de hacer. No hay nada mágico en una exportación predeterminada; es como cualquier otra exportación, excepto que se llama
"default".
En tu archivo test.js, la función "default" es inelegante porque quieres consumir la exportación default de ES6 desde una sintaxis ES5. Sugiero usar la sintaxis ES6 con la ayuda de TypeScript:
// test.ts
import GForest from "./build/GForest";
console.log(GForest); // { [Function: Forest] createTree: [Function] }
Este código se compila a:
var GForest_1 = require("./build/GForest");
console.log(GForest_1.default);
Exportar directamente una clase
En TypeScript, puedes exportar directamente un miembro con la sintaxis no estándar export =.
Ejemplo :
// GForest.ts
import * as Immutable from "immutable";
import GTree from "./GTree";
class Forest{
public static createTree(){
let tree = new GTree();
}
}
export = Forest;
Luego, úsalo con un código ES3/5:
// test.js
let GForest = require("./build/GForest");
console.log(GForest); // { [Function: Forest] createTree: [Function] }
... o, en TypeScript:
// test.ts
import GForest = require("./build/GForest");
console.log(GForest); // { [Function: Forest] createTree: [Function] }
Consulta la documentación sobre export = aquí.
Respuesta #2
¿Por qué hay un objeto con 'default' como clave y cómo puedo cambiar esto para lograr el comportamiento deseado?
Eso es porque es lo que se exporta desde el GForest.js compilado:
"use strict";
var GTree_1 = require("./GTree");
var Forest = (function () {
function Forest() {
}
Forest.createTree = function () {
var tree = new GTree_1["default"]();
};
return Forest;
}());
exports.__esModule = true;
exports["default"] = Forest;
Necesitas usar .default para referirte al constructor:
var GForest = require("./build/GForest").default;
Typescript utiliza la sintaxis de módulos es6 que puede exportar múltiples módulos. Este código luego se compila en la sintaxis de módulos commonjs es5. El compilador de Typescript utiliza propiedades en el objeto exports para mapear múltiples exportaciones definidas en la sintaxis de módulos es6. Y default es como cualquier otra exportación nombrada.
