Búsqueda de sitios web

node.js - Archivo de definición generado (.d.ts) por TypeScript no funciona con los typings de package.json


He creado un archivo de definición (d.ts) de mi proyecto TypeScript usando el argumento --declaration del compilador tsc.

Pero este archivo de definición generado aparentemente no funciona cuando intento publicar el paquete con la propiedad typings en el package.json de npm. He creado otro proyecto para probarlo.

Se queja con el mensaje: "El archivo de tipificaciones del paquete externo exportado ''...d.ts'' no es un módulo. Por favor, contacte al autor del paquete para actualizar la definición del paquete".

Estos son mis archivos fuente:

MiInterfaz.ts

export interface MyInterface
{
    MyProperty: string;
}

MiClase.ts

import {MyInterface} from './MyInterface';

export class MyClass implements MyInterface
{
    get MyProperty(): string
    {
        return "MyString";
    }
}

MiClaseHeredada.ts

import {MyClass} from './MyClass';

export class MyInheritedClass extends MyClass
{
    public MyMethod(): number
    {
        return 1;
    }
}

El comando tsc es este:

tsc MyClass.ts MyInterface.ts MyInheritedClass.ts --declaration -t es5 -outFile "mydefinition.js" --module "system"

Esta es la definición generada:

mydefinition.d.ts

declare module "MyInterface" {
    export interface MyInterface {
        MyProperty: string;
    }
}
declare module "MyClass" {
    import { MyInterface } from "MyInterface";
    export class MyClass implements MyInterface {
        MyProperty: string;
    }
}
declare module "MyInheritedClass" {
    import { MyClass } from "MyClass";
    export class MyInheritedClass extends MyClass {
        MyMethod(): number;
    }
}

¿Hay otra cosa que tenga que hacer o se supone que la definición generada no funciona en los typings de package.json?

Actualización para más detalles:

El escenario es que tengo 2 proyectos:

  • El primer proyecto es donde genero la biblioteca que publicaré en npm, y el package.json es donde pongo la propiedad typings vinculando al archivo mydefinition.d.ts generado por el comando tsc -d.

  • El segundo proyecto lo creo para probar el primero agregando el paquete (con tipados) generado.

Un enlace con los 2 proyectos y otros enlaces para el escenario:

https://github.com/jvitor83/typings-packagejson

Creo que el problema está con "Tus archivos de definición deberían escribirse como módulos externos" en el primer enlace. Pero quiero saber si hay una manera de generar esas definiciones para ponerlas en la propiedad typings del package.json.

Para reproducir el problema:

  • Clona este repositorio: https://github.com/jvitor83/test-typings-packagejson

  • Haz 'npm install', abre con VSCode y ve al archivo 'src/test.ts'.

Respuesta #1

La solución fue:

1 - añade un único archivo 'index.ts' que exporte todos los demás archivos.

export * from "./MyInterface"
export * from "./MyClass"
export * from "./MyInheritedClass"

2 - agregar en el proceso de compilación dos compilaciones/transpilaciones de los archivos (una para declaraciones y otra para el archivo js único [sin propiedad en el compilador tsc])

let tsConfigDeclaration = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true });
let tsConfigOneFile = gulp_typescript({module: 'system', target: 'es5', declaration: true, removeComments: true, out: 'typings-packagejson.js'});

Más información sobre el proceso de compilación: https://github.com/jvitor83/typings-packagejson/blob/master/gulpfile.js

y archivo de índice: https://github.com/jvitor83/typings-packagejson/blob/master/app/src/typings-packagejson.ts

Respuesta #2

¿Cuándo estás recibiendo este error?

Usé el archivo d.ts generado en otro proyecto y está funcionando bien.

   /// <reference path="mydefinition.d.ts" />

  import { MyInterface } from "MyInterface";
  import { MyClass } from "MyClass";
  import { MyInheritedClass } from "MyInheritedClass";

  let x: MyInterface = { MyProperty: "hello!!" };
  let y: MyClass = new MyClass();
  let z: MyInheritedClass = new MyInheritedClass();

Y al compilarlo está generando un archivo JS,

 /// <reference path="mydefinition.d.ts" />
 "use strict";
 var MyClass_1 = require("MyClass");
 var MyInheritedClass_1 = require("MyInheritedClass");
 var x = { MyProperty: "hello!!" };
 var y = new MyClass_1.MyClass();
 var z = new MyInheritedClass_1.MyInheritedClass();

¿Estás recibiendo este error al usar esto en algún archivo HTML? ¿Has incluido el archivo mydefinition.js en el HTML?

Actualizar

Basado en más detalles tuyos, aquí está la solución que puedo proponer: agrega otro archivo llamado index.ts y exporta todos tus módulos desde allí.

index.ts

    export * from "./MyInterface"
    export * from "./MyClass"
    export * from "./MyInheritedClass"

Agrega un archivo tsconfig.json para facilitar la compilación,

tsconfig.json

    {
     "version": "1.0.0",
     "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": false,
        "declaration": true,
        "outDir": "lib/"
    }       
   }

Nota: he hecho que sea un módulo commonjs (no estoy seguro si funciona para tu necesidad), genera la compilación usando el comando tsc. Generará archivos como los que se muestran a continuación, nota que ha agregado archivos js para todos los archivos ts y d.ts también es para todos los módulos, pero dado que hemos exportado todos los módulos desde un solo archivo, será más fácil de usar en el archivo package.json para el módulo de npm.

Luego agrega package.json en el módulo npm que deseas publicar como se muestra a continuación, consideremos que el nombre del módulo es foo

package.json

    {
     "name": "foo",
     "author": "author name",
     "version": "1.0.0",
     "main": "lib/index.js",
     "typings": "lib/index.d.ts"
    }

Ahora añade la carpeta foo dentro de node_module, la estructura final para el segundo proyecto será algo como lo siguiente,

Finalmente, en tu archivo test.ts importa y usa,

test.ts

    import { MyInterface, MyClass, MyInheritedClass } from "foo";

    let x: MyInterface = { MyProperty: "hello!!" };
    let y: MyClass = new MyClass();
    let z: MyInheritedClass = new MyInheritedClass();

Artículos relacionados