node.js - ¿Cómo escribo un archivo de declaración TypeScript para un módulo commonjs externo que tiene constructor?
POR FAVOR VEA LA PREGUNTA MÁS DETALLADA: ¿Cómo escribo un archivo de declaración de TypeScript para un módulo commonjs externo complejo que tiene un constructor, como imap?
Escribo TypeScript para una aplicación de Node.js, y quiero escribir un archivo de declaración de TypeScript para un módulo de JavaScript (disponible en npm) que tiene un constructor a nivel de módulo.
Aquí hay una versión simplificada del código relevante, en el archivo a.js:
function A(config) {
this.state = 'constructed';
}
A.prototype.update = function() {
this.state = 'updated';
};
module.exports = A;
y una aplicación de JavaScript simplificada, app.js, que usa el módulo a:
var mod = require('a');
var i = new mod({});
console.log('i.state=' + i.state);
i.update();
console.log('i.state=' + i.state);
¿Cómo escribo un archivo de declaración de TypeScript para el módulo a.js?
He leído la Guía de TypeScript para Escribir Archivos de Definición (.d.ts) pero, desafortunadamente, no pude averiguar cómo aplicar las directrices a este caso.
actualizado para incluir interfaces
Aquí está mi archivo de declaración a.d.ts:
declare module 'a' {
import events = require('events');
import EventEmitter = events.EventEmitter;
interface Config {
foo: number;
}
interface Other {
baz: number;
}
class A extends EventEmitter {
state: string;
constructor(config: Config);
update(): void;
}
var out: typeof A;
export = out;
}
No puedo averiguar cómo hacer que las interfaces estén disponibles para mi aplicación TypeScript. También quiero mantenerlas dentro del módulo, para que nombres como Config no colisionen con los de otros módulos.
Aplicación TypeScript añadida que usa esta declaración
Esto es lo que espero que se vea mi app.ts:
import mod = require('a');
import Config = mod.Config;
import Other = mod.Other;
var other : Other = {a: 2};
var config : Config = {foo: 2};
var i = new mod(config);
console.log('i.state=' + i.state)
i.update();
console.log('i.state=' + i.state)
Respuesta #1
Hay un par de maneras de hacer esto, aquí hay una:
declare class A {
state: string;
constructor(config: any);
update(): void;
}
declare module 'a' {
var out: typeof A;
export = out;
}
EDITAR: Si quieres incluir interfaces, pero también tener una clase exportada, puedes configurarlo así:
declare module A {
class A {
state: string;
constructor();
update(): void;
}
interface B {
value: any;
}
}
declare module 'a' {
var out: typeof A.A;
export = out;
}
Respuesta #2
Encontré un archivo de declaración existente para un módulo que tiene una estructura similar a la del archivo de declaración que quiero escribir: auth0
- auth0 en npm
- auth0.d.ts
Ahora tengo algo que funciona, aunque aún no es ideal. El archivo de declaración a.d.ts es:
/// <reference path='node.d.ts' />
interface Config {
foo: number;
}
declare module 'a' {
import events = require('events');
import EventEmitter = events.EventEmitter;
class A extends EventEmitter {
constructor(config : Config);
state: string;
update(): void;
}
var out: typeof A;
export = out;
}
con el archivo de la aplicación TypeScript app.ts siendo:
/// <reference path='a.d.ts' />
import mod = require('a');
var config : Config = {
foo: 1
}
var i = new mod(config);
console.log('i.state=' + i.state)
i.update();
console.log('i.state=' + i.state)
y el módulo a.js siendo como en la pregunta original.
Compilo esto con: tsc --module commonjs app.ts
Esto ciertamente funciona por ahora.
Aunque creo que es desordenado tener la interfaz (Config) fuera del módulo, todavía no he averiguado cómo mover las interfaces al interior.
