Typescript: Admite la búsqueda de módulos en node_modules al importar

Creado en 25 jul. 2014  ·  138Comentarios  ·  Fuente: microsoft/TypeScript

Actualización 5 de noviembre de 2015

La funcionalidad solicitada a continuación se implementa actualmente en mecanografiado desde al menos 1.8 con una diferencia principal:

En lugar de tener propiedades typescript.main y typescript.definition , solo hay una propiedad typings que puede apuntar a un archivo d.ts o a un .ts normal

Si está desarrollando un módulo para usarlo localmente, puede hacer que typings apunte a un archivo .ts , pero si planea publicar el módulo, se recomienda que apunte a un archivo d.ts . Esto se debe a que no desea que los consumidores de su módulo vuelvan a compilar los archivos de su módulo, solo consuman sus tipos.

He configurado un ejemplo de uso de esto aquí:
https://github.com/chanon/typescript_module_example

Hay una página de documentación aquí que tiene más información:
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

Gracias a los desarrolladores de TypeScript y a todos los colaboradores.

A continuación se presenta la solicitud de función/problema original


Motivación

En TypeScript es mucho más difícil reutilizar módulos de mecanografiados en comparación con reutilizar módulos npm en JavaScript.

Sería beneficioso si el compilador TypeScript fuera lo suficientemente inteligente como para buscar en las carpetas node_modules y en los archivos package.json.

El motivo es que los desarrolladores de módulos npm que usan TypeScript puedan comenzar a escribir y distribuir módulos a través de npm. TypeScript podría aprovechar la infraestructura de npm y su amplio soporte.

Ejemplo para node_modules

Si tuvieramos:

./node_modules/concator/index.ts
./myApp.ts

Y en index.ts teníamos:

export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}

en myApp.ts:

import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params

Básicamente, el compilador es lo suficientemente inteligente como para encontrar el módulo en node_modules y usa automáticamente la versión mecanografiada (index.ts).

Luego, cuando el código se compila en JavaScript, naturalmente usa la versión de JavaScript.

Importación de carpetas como módulos

Un caso más básico es admitir la regla popular de Node.js de http://nodejs.org/api/modules.html#modules_folders_as_modules como lo sugiere @vvakame a continuación y en el número 207 cerrado (semiduplicado).

mecanografiado.principal en paquete.json

Podría haber una adición a los archivos package.json para especificar dónde está el archivo .ts principal de un módulo npm de TypeScript. Esto sería similar a la clave main que especifica dónde está el archivo principal de JavaScript/.js pero para TypeScript en su lugar.

Por ejemplo, package.json para un módulo npm llamado "myModule" ubicado en node_modules/myModule/package.json

{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}

En este ejemplo node_modules/myModule/src/index.ts sería el archivo TypeScript principal y hacer import myModule = require("myModule"); importaría el archivo node_modules/myModule/src/index.ts .

Para un codificador JavaScript que escribe var myModule = require("myModule"); en un archivo JavaScript, el requisito cargaría el archivo node_modules/myModule/dist/index.js como de costumbre.

Como se puede ver en este ejemplo, el src de TypeScript está en la carpeta node_modules/module-name/src y los archivos JS compilados estarían en node_modules/module-name/dist .

Algo como esto podría ser un (semi) estándar para los módulos npm de TypeScript para que la fuente de TypeScript se separe claramente de la salida de JavaScript compilada.

Un caso más básico, como lo sugiere @vvakame a continuación, es compatible con la regla popular de Node.js de http://nodejs.org/api/modules.html#modules_folders_as_module

mecanografiado.definición en paquete.json

Otra clave posible para package.json para módulos npm que no sean de TypeScript (JavaScript simple) podría ser typescript.definition . Esto apuntaría a un archivo .d.ts que define el módulo para los usuarios de TypeScript del módulo npm.

para que un
import $ = require('jquery');
leería automáticamente un archivo jquery.d.ts definido en la clave typescript.definition en jQuery's package.json y convertiría a $ el tipo correcto.

Formato de ejemplo:

{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}

(Tsd ya usa este formato como explica @Bartvds a continuación).

Entonces nosotros, los codificadores de TypeScript, tendríamos que intentar obtener la mayor cantidad posible de mantenedores de módulos npm que no sean de TypeScript para fusionar nuestras solicitudes de incorporación de cambios que tienen nuestros archivos .d.ts y claves de paquete.json typescript.definition .

Si tenemos éxito con eso, entonces la vida de los codificadores de TypeScript sería una bendición... no más administración separada de archivos DefinitelyTyped .d.ts. ¡Simplemente instale npm y obtendrá sus definiciones de TypeScript también! Automáticamente y actualizado con la versión del módulo instalado.

Lista de Beneficios

Lo que obtenemos de todo esto es

  • Los módulos npm se pueden escribir en TypeScript.
  • Tanto los codificadores de TypeScript como de JavaScript pueden usar estos módulos
  • Los usuarios del módulo que usan TypeScript obtienen los beneficios de la escritura estática sin que el codificador del módulo (o el usuario) tenga que usar el método habitual de escribir (o generar) archivos .d.ts separados (por lo que cuando el código fuente del módulo ya está en TypeScript no tenemos que tener otro archivo .d.ts para mantener)
  • Habría una manera de reutilizar y distribuir fácilmente los módulos de TypeScript usando npm con los que todos ya están familiarizados.
  • Podría ayudar a promover el uso de TypeScript en sí mismo, ya que los codificadores de JavaScript que usan los módulos npm escritos en TypeScript podrían ver cuán agradable/mejor es la fuente de TypeScript e intentar cambiar a ella. O podrían querer contribuir al módulo y dado que la fuente está en TypeScript, tendrían que aprenderlo, lo que puede hacer que les guste y decidan usarlo en sus propios proyectos.
  • Básicamente, ayudaría a hacer crecer la comunidad de TypeScript a través de todo el código compartido que podría resultar. En este momento, el código TypeScript de todos es principalmente suyo/en su propio silo. En realidad, esto es probablemente algo extremadamente importante, ya que no tener una forma adecuada/fácil de compartir/distribuir/reutilizar módulos probablemente esté limitando el crecimiento del lenguaje. [1]
  • La reutilización de módulos en proyectos internos sería mucho menos complicada y reduciría la necesidad de todas esas rutas relativas a archivos .d.ts y rutas relativas en requisitos de módulos, y cosas generales de .d.ts. (En este momento, cuando escribo código TypeScript, encuentro que tengo que aprender a ser bueno contando ../../ s)
  • Este enfoque también es compatible con Browserify/Webpack, ya que Browserify/Webpack también busca en node_modules, por lo que permite módulos de TypeScript distribuidos fácilmente reutilizables/npm tanto para el servidor como para el navegador.
  • Los módulos npm que no son de TypeScript se pueden usar fácilmente en TypeScript con información de tipo mediante la adición de la tecla typescript.definition . Esto permite que los archivos de definición .d.ts se empaqueten junto con el módulo npm para que la actualización de un módulo npm actualice automáticamente su archivo de definición .d.ts. Esto elimina la necesidad de actualizar los archivos .d.ts manualmente.
  • Usar archivos de definición a través de typescript.definition es más simple porque es simplemente una declaración import moduleName = require("moduleName") sin necesidad de ///<reference ... por separado
  • El uso de archivos de definición a través de typescript.definition también debería permitir el uso de diferentes versiones del módulo en la misma base de código sin que los nombres de tipos entren en conflicto.

Propuesta detallada

@ Nemo157 ha escrito una propuesta muy detallada sobre cómo debería funcionar todo esto en:

TypeScript propuesto requiere semántica de resolución
https://gist.github.com/Nemo157/f20064a282ee620f3877

Una adición a la propuesta es el uso de carpetas /typings que pueden contener archivos de definición que pueden administrarse automáticamente mediante herramientas como tsd para módulos JavaScript npm que no incluirán archivos de definición en sus repositorios. .

Hechos finales de apoyo

Dado que TypeScript se compila en JavaScript, que se ejecuta principalmente en dos lugares: node.js y en los navegadores, admitir node_modules es beneficioso para ambos lugares (prácticamente todos los lugares donde se usa TypeScript) debido a npm y Browserify/Webpack.

es decir. no hay razón para idear un esquema diferente cuando node_modules es lo que todos los usuarios de TypeScript ya usan para quizás el 75% -100% de todo su código JavaScript. (Quitando el 25% para los usuarios de RequireJS).

notas al pie

[1] - Por cierto, veo que hay un administrador de paquetes NuGet (?) de Microsoft que puede distribuir módulos TypeScript (?), pero viniendo de un fondo enfocado en node.js (no enfocado en .NET), no veo que NuGet se convierta en ampliamente utilizado fuera de las tiendas enfocadas en Microsoft, especialmente porque npm es _el_ estándar para node.js y también es un estándar líder para JavaScript del lado del cliente. Si no hubiera usado TypeScript, nunca habría oído hablar de NuGet. El codificador de JavaScript del lado del cliente/node.js promedio probablemente preferiría usar npm, la misma herramienta que ya usan en lugar de tener que usar algo específico de Microsoft, como NuGet. (En realidad, no sé nada sobre NuGet, por lo que lo que estoy diciendo aquí podría no importar).

Committed Suggestion

Comentario más útil

En cualquier caso, el compilador afirma actualmente que no puede encontrar el módulo, cuando en realidad simplemente se niega a importar el módulo sin una definición de tipo. Eso no es realmente útil, ¿verdad?

Todos 138 comentarios

[movido a typescript.main en package.json en la descripción del problema anterior]

:+1:
Creo que http://nodejs.org/api/modules.html#modules_folders_as_modules es una regla muy popular de Node.js.

otro ejemplo

./prueba/index.ts

export function hello() { return "Hello, world"; }

./main.ts

import test = require("./test/");
console.log(test.hello()); // print "Hello, world"

[movido a typescript.definition en package.json en la descripción del problema anterior]

Una solución sería resolverlo con mejores herramientas. Por ejemplo import foo = require('foo') le da una pista para buscar algún node_module+package.json local (foo es un proyecto ts) o definición de DT (foo es un proyecto js donde los autores de la biblioteca no quieren mantener la definición de ts) .

para su información; De hecho, estoy probando algo similar a esto en TSD; una forma de exponer y vincular definiciones que se incluyen en los paquetes npm (o bower).

Está en mi versión de desarrollo para 0.6 y funciona agregando un elemento typescript al paquete.json (o bower.json), con un subelemento definition (un subelemento porque tal vez uno día habría source también, o lo que sea).

{
    ...
    "main": "./index.js",
    "typescript": {
        "definition": "./foo.d.ts"
    }
    ...
},

Luego puede ejecutar un comando en TSD, actualmente tsd link y escaneará todos los archivos package.json en node_modules (o bower o lo que sea), encuentre esa propiedad si está definida y agregue una referencia a ella en el tsd.d.ts central

Ejemplo: definido aquí y uso aquí

@Bartvds Eso es bastante bueno. Podría ser el primer paso para tener .d.ts en paquetes npm. Me gusta la estructura de package.json con "definición" en "mecanografiado", está mucho más organizada.

Si el compilador de TypeScript pudiera leerlo automáticamente, sería genial.

Etiquetar esto para discusión: una resolución de módulo externo más inteligente es algo de lo que debemos hablar para comprender los diversos escenarios aquí. Esto se mencionó anteriormente e hicimos algunos ajustes en 1.0.

También discuta # 207 - mirando debajo de 'índice'

:+1:

@chanon tsMain no es necesario si usamos generación de declaraciones.

Sí, el problema es inmensamente importante incluso para los navegadores: muchos proyectos usan browserify/packify y, por lo tanto, diseños de directorio compatibles con nodos.

:+1:

Ya ha habido algo de trabajo en esta área en el repositorio de codeplex, una solicitud de extracción de leebyron y otra de kayahr .

Tenía la intención de intentar portar uno de ellos al nuevo repositorio, pero parece que el código relacionado se ha reorganizado mucho.

He escrito una propuesta sobre cómo agregar esto al compilador de TypeScript . Esto también incluye buscar en el directorio typings , ya que será importante cuando se trabaje con módulos de JavaScript que no mantendrán sus propias definiciones de mecanografiado. Desafortunadamente, hacer que todo esto funcione de manera transparente con tsd aún requerirá un poco de trabajo, ya que el requisito de que los archivos /// <reference d sean declaraciones ambientales externas complica un poco las cosas. Echaré un vistazo a la implementación de esto en una rama y proporcionaré algunos módulos de ejemplo usándolo.

Parece sensato. ¿Cubrirá esto módulos con dependencias de tipo en conflicto? Quiero decir, si una aplicación importa A y B, y B también depende de A. Es fácil caer en errores de tipo duplicado si hay dos copias de las declaraciones externas.

No debería, deberían resolverse en diferentes nombres de módulos externos, por lo tanto, declare tipos independientes con nombres idénticos en diferentes módulos. La verificación del tipo estructural debería permitir que los diferentes módulos interactúen sin problemas.

Ese es uno de los principales problemas con las definiciones actuales tsd que esto está tratando de resolver, al definir módulos ambientales externos, no hay forma de que manejen tener múltiples versiones de una biblioteca con nombres idénticos, pero tipos ligeramente diferentes. .

@joewood también habrá problemas entre las diferentes versiones de A

├── [email protected]
└── [email protected]
    └── [email protected]

no hay forma de que manejen tener múltiples versiones de una biblioteca con nombres idénticos, pero tipos ligeramente diferentes.

interesados ​​en conocer soluciones al mismo. TypeScript tiene un alcance de variable de nivel global para declaraciones ambientales

Incluso si las versiones coinciden, en este momento veo problemas con dos archivos de declaraciones ambientales diferentes pero coincidentes que causan errores de símbolos duplicados. La directiva /// reference definida localmente debe resolverse de alguna manera en un solo archivo. O eso, o la identidad de tipo debe incluir la ruta y la tipificación estructural se encargará de las discrepancias de versión, etc.

@joewood Sí, eso es lo que espero que se solucione en la mayoría de los casos cambiando require para cargar las definiciones correctas, evitando /// reference siempre que sea posible. Los módulos externos se identificarán por sus rutas absolutas en lugar de tener declaraciones ambientales, por lo que debería ser posible cargar múltiples del mismo nombre desde diferentes rutas y en diferentes versiones.

Sí, eso es lo que espero que se solucione en la mayoría de los casos cambiando require para cargar las definiciones correctas, evitando la referencia /// siempre que sea posible.

:+1:

:+1: Gracias @Nemo157 ya todos por la discusión.

Actualicé el texto del problema principal para fusionar las adiciones de package.json y lo vinculé a la propuesta de @ Nemo157 .

:+1:

Realicé una implementación inicial de mi propuesta junto con la creación de un conjunto de módulos de ejemplo para mostrar que todas las diferentes formas de hacer un módulo funcionarán. Incluyendo el uso de diferentes versiones de la misma biblioteca en diferentes submódulos.

:+1:

Carpetas como módulos con index.ts :+1:

:+1:

:+1:

:+1:

:+1:

:+1: :+1: :+1:

:+1: :+1: :+1: :+1:

Comentando para volver a poner esto en nuestro radar.

He tenido mucho éxito con la sugerencia de @Bartvds :

Luego puede ejecutar un comando en TSD, actualmente tsd link y escaneará todos los archivos package.json en node_modules (o bower o lo que sea), busque esa propiedad si está definida y agregue una referencia al paquete central tsd.d.ts en tu proyecto

Así que definitivamente considere apoyar a typescript en package.json ya que esa es la forma en que la comunidad se ha ido.

Definitivamente necesitamos que tsc esté al tanto de la carpeta node_modules si TypeScript se va a usar ampliamente en la comunidad de node.js. Actualmente uso enlaces simbólicos a módulos que son parte de mi proyecto de desarrollo (usando npm-workspace), y tengo dos opciones en este momento:

  • importar directamente desde node_modules, que se ve mal: import Foo = require("node_modules/mymodule/Foo");
  • obtenga tsc para generar los archivos de declaración y luego únalos usando un archivo de declaración de módulo mantenido manualmente que cambia los nombres de los módulos de cadena

¿Podría tsc verificar el nombre del módulo externo en las declaraciones de importación y luego, durante la resolución de la ruta, también aplicar node_modules de la misma manera que lo hace el tiempo de ejecución de node.js? Una opción del compilador también podría activar o desactivar esto.

:+1: :+1: :+1:

¿Podría tsc verificar el nombre del módulo externo en las declaraciones de importación y luego, durante la resolución de la ruta, también aplicar node_modules de la misma manera que lo hace el tiempo de ejecución de node.js?

Así es como debería ser. La forma actual de simplemente buscar en el árbol de directorios para encontrar un archivo con dicho nombre no se parece a los contextos de ejecución de JS.

Esto ha estado en mi lista desde hace un tiempo. intentará obtener esto en la próxima versión.

Nosotros ( Booktrack ) usamos TypeScript para todo nuestro desarrollo web y enfrentamos desafíos similares a los de los desarrolladores de node.js. Hablo porque la voz de los desarrolladores web no parece tan alta como la de los desarrolladores de nodos.

Soluciones (en orden de lo peor para nosotros a lo mejor para nosotros):

  1. resolución de nombres de módulos externos de nivel superior a través de búsqueda codificada en node_modules
  2. no hay control sobre la resolución de nombres de módulos externos de nivel superior
  3. un indicador del compilador para controlar la resolución opcional de los nombres de los módulos externos de nivel superior en el directorio node_modules
  4. un parámetro de "ruta (s) de búsqueda de módulo" del compilador para controlar la resolución opcional de los nombres de módulos externos de nivel superior en la (s) ruta (s) dada (s)
  5. un parámetro de "resolución de módulos" del compilador para proporcionar al compilador un complemento JS que resolverá todos los nombres de módulos externos (no solo los de nivel superior)
  6. ganchos apropiados en los servicios de lenguaje de modo que la resolución de nombres de módulos externos sea controlable

La opción 1 es terrible, prefiero la opción 2.

Las opciones 5 y 6 permitirían usos exóticos de declaraciones de importación, como las que se encuentran cuando se trabaja con los complementos requirejs o webpack. La idea básica: el compilador delega todas las búsquedas de nombres de módulos externos (no solo de nivel superior) a un tercero (un complemento o devolución de llamada). El delegado, dada la ruta al módulo en compilación y el nombre del módulo externo, devuelve al compilador la ruta del sistema de archivos O la información de tipo para el nombre del módulo dado.

Estaría feliz si se implementara la opción 4, encantado si se implementara la opción 6 y feliz si se implementaran tanto la opción 4 como la opción 6.

¿Qué tal un --basePath para la raíz de búsqueda de su módulo? Todas las importaciones de módulos se buscarán en relación con esa ruta. Esto solo aplica para AMD.

Creo que el tema del nodo es mucho más simple, solo necesitamos implementarlo :)

Tenga en cuenta que obtuvimos una implementación (y pruebas) de @ Nemo157 aquí hace mucho tiempo https://github.com/Microsoft/TypeScript/issues/247#issuecomment -57422329

De acuerdo con @mark-buer y @mhegazy , la opción 4, una ruta de búsqueda, debería ser una solución simple. Definitivamente se requiere una solución más elaborada en el servicio lingüístico (opción 6) a más largo plazo.

_Vale la pena agregar_: esto por sí solo no solucionará el problema de reutilización de TypeScript en npm debido al problema del símbolo duplicado para las referencias de tipo común #1125. Realmente tenemos que evitar ///mediante el uso de archivos .tsconfig y arregle esto correctamente al agrupar paquetes en un solo módulo externo escrito como se sugiere en el n. ° 17

Otro voto para que el compilador mecanografiado reconozca la carpeta node_modules.

Para los módulos de CommonJS, TypeScript idealmente debería seguir la misma resolución de nombre de archivo que require.resolve (como se describe en el psuedocódigo en esta página: http://nodejs.org/api/modules.html#modules_all_together.

esta funcionalidad es fundamental para permitir la integración del compilador TypeScript en otros empaquetadores de nodos, como browserify. El parche de @ Nemo157 hace un buen trabajo, pero no permite realizar pruebas fácilmente con los empaquetadores existentes, ya que la mayoría pasó a versiones posteriores de TypeScript y ya no son compatibles con su código.

¿Dónde tiene que estar el directorio node_modules en relación con las fuentes?

Atom-TypeScript ahora admite typescript.definition de fábrica. Detalles: https://github.com/Microsoft/TypeScript/issues/2829

También puede crear tales paquetes fácilmente usando atom-typescript :rose: de nuevo vea #2829

Limitación

Funcionará _perfectamente_ si comparte un paquete que no depende de ninguna biblioteca externa. Si es así, entonces necesitamos un algoritmo de resolución de conflictos del módulo.

Estoy abierto a sugerencias para este caso, pero mi plan es:

  • hacemos algunas cosas inteligentes al leer tal d.ts sin darle a TypeScript los comentarios externos reference (por ejemplo, node.d.ts aquí https://github.com/TypeStrong/atom-typescript-examples /blob/master/node/node_modules/example-typescript-b/definition/sample-bdts) Y en su lugar apuntar a nuestro propio .d.ts si lo tenemos en nuestros Typings.

¿Esto va a mantenerse en el camino para 2.0? Parece una especie de característica importante para la adopción de Node.js, que en este momento es dolorosa, incluso con DefinitelyTyped y similares.

Parece una especie de característica importante para la adopción de Node.js, que en este momento es dolorosa, incluso con DefinitelyTyped y similares.

@LPGhatguy Consulte https://github.com/Microsoft/TypeScript/issues/2338. @vladima está trabajando en ello, pero no creo que se le haya asignado ningún hito todavía :rose:

@LPGhatguy estamos tratando de obtener esto en la próxima versión. espero que pronto.

@mhegazy ¿Quieres decir 1.6? ¡Que sería increíble!

¿Está eso relacionado con el #2338?

sí para TypeScript 1.6 (al menos esto es lo que estamos tratando de hacer), y sí para #2338; hay un par de otros cambios y problemas relacionados con esto, incluidos #3147 y #4154

Entonces, ¿por qué se etiqueta como TypeScript 2.0 como hito?

gracias @heycalmdown , eliminó el hito. no solemos etiquetar hitos en las sugerencias. esperemos que tengamos una actualización dentro de una semana más o menos sobre este tema. Manténganse al tanto.

Me gustaría pedir ayuda para el módulo ES6 para seguir esto también (¿lo cual supongo que sería?)

mecanografías para

import mylib = require('mylib');
mylib.foo(mylib.bar);

debe comportarse igual que

import { foo, bar } from 'mylib';
foo(bar);

Me gustaría pedir ayuda para el módulo ES6 para seguir esto también (¿lo cual supongo que sería?

@DavidSouther Ese sería _automáticamente_ el caso. La búsqueda entre los dos es consistente :rose:

esto es manejado por #4154.

Si uso todas las noches, a partir de mañana debo esperar que la importación de módulos de nodo "simplemente funcione".

Pregunta:
Creo que es una convención común tener archivos llamados
"índice" en commonJS y
"principal" en AMD
para caminos cortos.
En la pregunta de arriba el autor importa
/node_modules/concator/index.ts como
import concator = require('concator');

Por favor, perdóname. Actualmente estoy averiguando si la resolución de índice también es compatible ahora y ¿qué tal si index.ts o main.ts en AMD requieren resolución?
También estoy haciendo ping a @basarat para saber si es/será compatible con https://github.com/TypeStrong/atom-typescript porque ahora no me permite solicitar ningún index.ts como se mencionó anteriormente.

@sebilasse , si está usando typescript@next hoy, esto debería funcionar con --module commonjs

import concator = require('concator'); // resolves to node_modules/concator/index.ts

No hay cambios en la resolución de AMD con respecto a versiones anteriores.

@DavidSouther debería estar en typescript@next hoy. Pruébelo y háganos saber cómo le va.

@mhegazy @basarat :+1: está bien. Pero, ¿cómo piensa acerca de la resolución de AMD para main.ts o index.ts? ¿No debería ser consistente en el futuro?

@sebilasse , para AMD, creo que debemos hacer algo como lo señaló @vladima en el n.° 2338 (sección para: cargador de módulos RequireJS/ES6).

¡¡Muy agradable!! \o/

@mhegazy Todavía no funciona como esperaba.

Reuní https://github.com/DavidSouther/typescript-example-using-node con mi caso de uso "ideal". tslib es una biblioteca simple que exporta una sola función. tsclient depende de tslib, así como readline de los paquetes de Node. La secuencia de comandos de instalación es conveniente para instalar, vincular y ejecutar. Incluí una ejecución y anoté las partes inesperadas con comentarios en línea.

% ./setup
...
> [email protected] build ~/ts-node/tslib
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
...
> [email protected] build /Users/southerd/devel/tmp/ts-node/tsclient
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
# Expect this to find tslib, but fail type checking.
# See tsclient/app.ts for details
src/app.ts(4,21): error TS2307: Cannot find module 'tslib'.

+ node ./dist/app.js # This works as expected!
What would you ask? What is the meaning of life?
42
+ set +x

Tampoco recibo soporte de idioma para las importaciones de tslib en tsclient (VSCode versión 0.7.0 (0.7.0)), aunque no estoy completamente seguro de qué TSC está usando o cómo cambiarlo.

El compilador @DavidSouther TypeScript verifica el campo 'typings' en package.json para encontrar archivos '.d.ts'. Con este cambio obtengo src/app.ts(13,7): error TS2322: Type 'string' is not assignable to type 'number'. que parece un error legítimo

Ah, debo haberme perdido esa pieza de documentos. Todavía tengo el segundo problema: ¿cómo cambio la versión de VSCode tsc?

puede proporcionar una ubicación personalizada del SDK de TypeScript a VSCode a través de la configuración "typescript.tsdk" ; debe apuntar a la carpeta que contiene tsserver.js y los archivos estándar '.d.ts'. En caso de que TypeScript esté instalado como paquete npm, será algo así como

// Place your settings in this file to overwrite the default settings
{   
    "typescript.tsdk": "C:\\Sources\\bugs\\node\\typescript-example-using-node\\tslib\\node_modules\\typescript\\lib"       
}

¿Alguien consiguió una muestra de trabajo? Intenté toda la tarde jugar con esto, pero siempre termino con

error TS2307: Cannot find module

Por el momento el código está en node_modules/my-module/. Y definí un index.ts que se encarga de exportar todo, y lo mencioné en el paquete.json en typescript.main. En el proyecto del consumidor, intenté importar {AClass} desde 'my-module'; e import my-module = require('my-module'); Ambos conducen al mismo error con TypeScript 1.7.0-dev.20150901.

Al resolver un módulo con nombre no relativo, con --module commonjs , el compilador buscará un .d.ts que coincida con el nombre en node_modules\name\index.d.ts o buscará en package.json para una propiedad typings y cargue el .d.ts al que apunta.

a partir de su descripción, parece que lo está configurando en index.ts , realmente no desea compilar sus dependencias, solo desea consumir sus tipos, por lo que debe configurarlo en index.d.ts en su lugar.

Actualicé los pasos en el algoritmo de resolución del módulo de nodo para reflejar la implementación: https://github.com/Microsoft/TypeScript/issues/2338

@DavidSouther Aparentemente tengo exactamente el mismo problema. Cuando compilo con una dependencia en node_modules, no puede resolver el módulo y genera un error, pero aún genera el js, y si lo ejecuto, se ejecuta. Tal vez se deba a mi configuración, no lo sé. Mi d.ts está mayormente vacío, tengo un index.ts que se encarga de importar y reexportar todas las clases de mis módulos definidos en muchos archivos .ts. Y luego mi archivo d.ts solo hace referencia a este index.ts y exporta todo desde index.ts de esta manera:

/// <reference path="index.ts" />

declare module 'my_module' {
    export * from 'index';
}

Además, de alguna manera aún compila los ts de node_modules, por lo tanto, debo agregar una tarea limpia para eliminarlo después de la compilación. ¿Hay una descripción de la función en alguna parte que resuma el proceso?

editar: lo hice funcionar, pero es súper hacky y aún genera errores. Creé un d.ts con dts-generator y luego importé mis clases de esta manera:

import MyClass from '../../node_modules/my_module/dist/MyClass';

Si utilizo import MyClass from 'my_module/MyClass', obtengo que se compile sin error, pero en el tiempo de ejecución aparece el error no puedo encontrar el módulo 'my_module/MyClass'. Con la solución anterior, apunta directamente al .js compilado y en tiempo de ejecución funciona de alguna manera, aunque genera el error no se puede encontrar el módulo en tiempo de compilación.

Todavía tengo problemas para importar desde submódulos (por ejemplo, npm install angular2, import { Inject, Binding } from 'angular2/di' . Trabajará para obtener un caso de prueba contenido esta noche.

No crea que angular ya agrupa sus tipos de la forma esperada por el compilador de TypeScript.

Eso es probablemente cierto; Trabajaré con ellos y veré dónde termina.

esta función funciona bien en TypeScript 1.1, por ejemplo https://github.com/Nemo157/typescript_w_node_modules_example

pero falla en mecanografiado 1.5.3, ¿ha cambiado algo?

------ actualizar ---------

Sé que se lanzará en 1.6, gracias

Solo puedo obtener este "medio trabajo" en 1.6.2

Primero, empaqueto una biblioteca con un my-lib.d.ts en el directorio dist , y apunto a este archivo en el atributo package.json del archivo typings (por ejemplo "typings" : "dist/my-lib.d.ts" )

Luego importo esta biblioteca en un archivo TypeScript Test.ts usando

import { MyObject } from "my-lib"

MyObject se importa correctamente y el código js se emite en la transpilación.
Visual Studio Code incluso proporciona finalización en MyObject

Sin embargo, recibo advertencias del compilador de que:
Test.ts(10,60): error TS2306: File '[]/node_modules/my-lib/dist/my-lib.d.ts' is not a module.

Visual Studio Code realmente mostrará la importación como un error grave

Todos los módulos importados de un paquete de nodos deben ser "módulos externos" y no "declaraciones de módulos ambientales". es decir, no hay declaraciones declare module "foo" {.. } , sino declaraciones de importación o exportación de nivel superior en el archivo.

Entonces, si su paquete "my-lib" está escrito en mecanografiado, simplemente constrúyalo con --declarations y establezca los tipos en el archivo .d.ts de su módulo principal. si no, y sus escrituras son algo que usted escribió a mano, o que obtuvo de una escritura definitiva, entonces deberá cambiarlo a un módulo externo o esperar hasta que se resuelva # 4665 (con suerte pronto).

El motivo de esta restricción es que puede causar contaminación de alcance global y conflictos más adelante para los usuarios de su paquete. hay una larga discusión sobre esto en #4665.

Aquí hay alguna documentación para futuras búsquedas: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

@mhegazy Gracias por su rápida respuesta, que realmente me ayudó en mi búsqueda para automatizar la compilación de bibliotecas commonjs, escritas en TypeScript, que pueden ser consumidas por código Javascript y TypeScript.
La sintaxis y la resolución import/export se han movido tan rápido recientemente que lo que creo que falta en este momento es una guía definitiva sobre cómo construir una.

Lo tengo funcionando... con una advertencia (y por lo tanto otra pregunta)

Aquí hay una vista simplificada de la configuración.

La biblioteca consta de tres objetos A1, A2 y B en 2 archivos mecanografiados A.ts y B.ts; algo como

fuentes

A.ts

class A1{}
class A2{}
export { A1, A2 }

B.ts

class B{}
export { B }

Lo que queremos exponer está recogido en un index.ts :

export * from './A'
export * from './B'

construir
La compilación se lleva a cabo con la ayuda de grunt y los indicadores --module commonjs y --declaration se establecen en tsc 1.6.2
El resultado final de la construcción es un árbol que parece

    package.json
    dist/
        js/
             A.js
             B.js
             index.js
        typings/
             A.d.ts
             B.d.ts
             index.d.ts

package.json contiene estas dos entradas:

"main": "dist/js/index.js",
"typings": "dist/typings/index.d.ts"

Usar esta biblioteca en TypeScript 1.6.2 con un simple import {A1, A2, B} from "mylib" funciona absolutamente bien. Las dependencias de múltiples niveles (es decir, las bibliotecas que se importan entre sí) también funcionan bien.

Donde surgen problemas es cuando la biblioteca depende de otra biblioteca que _no_ es una biblioteca de TypeScript.
Digamos que la biblioteca depende de Node.js.
En uno de los archivos fuente habrá una referencia a los tipos de NodeJS, por ejemplo
///<reference path="../typings/node/node.d.ts"/>

Tras la transpilación, esa instrucción <reference > terminará en el archivo de declaración correspondiente; el problema es que es probable que la ruta a node.d.ts sea ​​incorrecta o inexistente.
¿Hay una manera recomendada de hacer esto?

_Nota_: este problema se alivia con el uso de un archivo index.ts para exponer las partes interesantes de la biblioteca, ya que index.ts no tiene por qué contener una instrucción <reference > y con 1.6 .2, al compilador no parece importarle que Adts tenga una ruta no válida en la instrucción de referencia

@bgrieder Manejamos esto en Phosphor usando tsconfig.json :
https://github.com/fosforjs/fosforo-widget/blob/master/src/tsconfig.json

Simplemente agregamos los tipos externos que necesitamos a los archivos compilados. Esto significa que si alguno de esos tipos externos es parte de nuestra interfaz pública, los consumidores del código también deberán proporcionar esos tipos externos como parte de su compilación. _Esto está bien_. Si tuviéramos que agrupar esas definiciones, y alguna otra librería utilizada por el consumidor _también_ agrupara esas mismas definiciones, habría conflictos de símbolos duplicados.

@sccolbert ¡Sí!
Me preocupaba que la eliminación de las instrucciones <reference ...> rompiera el autocompletado en todos los IDE, pero bueno, no: al menos Visual Studio Code 0.8.0 parece ser lo suficientemente inteligente como para elegir esas definiciones del tsconfig.json archivo! (después de un reinicio)

Listo con reference . Excelente !

@sccolbert

¿Qué sucede si está utilizando un proyecto simple Node.js dentro de él y *.d.ts para él? ¿Cómo lo ayuda la solución tsconfig ?

@heycalmdown , simplemente agregue d.ts al campo files en tsconfig , aquí hay un ejemplo que hace eso:

https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/tsconfig.json#L11
https://github.com/fosforjs/fosforo-widget/blob/master/test/src/index.ts#L10

Tenga en cuenta que tenemos que usar require aquí en lugar de import solo porque el archivo d.ts para expect.js está escrito internamente.

Esta bien, lo tengo. Sus repositorios parecen una especie de buen ejemplo.

¿Se ha implementado esto realmente en TypeScript 1.6.2?

Si es así, ¿alguien puede decirme qué estoy haciendo mal aquí?:
https://github.com/chanon/typescript_module_example

Probablemente desee la sintaxis de importación es6.

El miércoles 4 de noviembre de 2015 a las 6:10 a. m., chanon [email protected] escribió:

¿Se ha implementado esto realmente en TypeScript 1.6.2?

Si es así, ¿alguien puede decirme qué estoy haciendo mal aquí?:
https://github.com/chanon/typescript_module_example


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/Microsoft/TypeScript/issues/247#issuecomment-153688004
.

Acabo de actualizarlo para usar la sintaxis de importación es6 y sigo teniendo los mismos errores (no puedo encontrar el módulo).

@chanon el package.json para node_modules paquetes deben tener una clave typings que apunte a un archivo d.ts , _no_ una clave typescript que apunte .ts archivos como los que tiene ahora.

Usamos la resolución de módulos de nodo en PhosphorJS exclusivamente (en TS 1.6.2) y funciona bien. Aquí hay un ejemplo: https://github.com/phosphorjs/phosphor-widget/blob/f908341cb1d46ada8ad8149e695a75e7ea2fde57/package.json#L6

Gracias @sccolbert , sin embargo, mi propuesta inicial (en la parte superior de este problema) fue permitir una propiedad typescript.main en package.json que apuntaría al punto de entrada principal de TypeScript para los paquetes de módulos de nodos escritos en mecanografiado.

Esto permitiría importar módulos TypeScript en código TypeScript sin la necesidad de archivos de escritura d.ts (ni siquiera habría necesidad de generarlos).

@chanon Solo estaba señalando lo que debe hacer para ejecutar su código.

@sccolbert Veo gracias.

¿Puede alguien que sepa decirme si debo crear otro problema solicitando esta característica específica?

Los principales problemas relacionados con la lógica de resolución del módulo (aparte de este) parecen ser el n. ° 2338, que está cerrado, y el n.

Sin embargo, ¿parece haberse olvidado la simple importación de estilo CommonJS como se solicitó inicialmente en este problema? ¿Al menos la parte sobre typescript.main y carpetas como módulos?

No entiendo la necesidad de tener (y el deseo de tener) archivos d.ts si tanto el módulo como el consumidor del módulo ya están escritos en TypeScript.

En realidad, no es muy diferente de importar un archivo TypeScript relativamente ex.

En lugar de tener que hacer:
import * as lib from '../relative/path/to/typescriptFile.ts'

O:
import * as lib from '../../node_modules/myModule/index.ts'

Simplemente deje que TSC pueda encontrar el archivo mecanografiado para importar utilizando la resolución de ruta normal de node_modules. Y al menos permitir la importación de carpetas como módulos (con un index.ts) para que en el segundo ejemplo pueda hacer:

import * as lib from 'myModule'

¿O es porque "realmente no quieres compilar tus dependencias, solo quieres consumir sus tipos"?

@chanon , el comportamiento que describe es lo que está en el maestro ahora. ¿Puedes probar typescript@next ?

la implementación original de # 2338 agregó algunas verificaciones adicionales para garantizar que sea un .d.ts, y eso es principalmente por la razón que mencionó. no desea que los usuarios de su paquete compilen sus "fuentes" en cada invocación del compilador y obtengan resultados diferentes según las opciones del compilador, solo desea compartir sus tipos.

Sin embargo, si está creando ambos paquetes, es posible que desee hacerlo mientras los itera. La restricción se eliminó en el #5278.

Eche un vistazo a la página wiki para compartir tipeos a través del paquete npm para obtener más información: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

¡Gracias por tu aclaración @mhegazy! Voy a tratar de salir.

@mhegazy Acabo de probar con typescript@next , ¡funciona como se esperaba!

¡¡Esto es genial!!

Y gracias a todos por participar en este y otros temas relacionados :+1:

Agregué una actualización al texto del problema anterior para explicar la forma en que se implementó esta función.

A riesgo de entrar en un campo minado, ¿cómo se espera que esto funcione con módulos npm simples que _no_ tienen una propiedad typings en package.json? Intentar usar tape o get-parameter-names con typescript@next hace que me explote en la cara porque no puede encontrar esos paquetes debido a que no tienen eso. propiedad.

Claro, no son módulos mecanografiados, pero parece que no puedo encontrar una solución y eso bloquea una parte significativa del ecosistema npm.

@danpantry Por lo general, usaría un archivo .d.ts normal escrito específicamente para ese módulo. El proyecto DefinitelyTyped tiene archivos .d.ts para muchos módulos comunes. Existe una utilidad tsd que puede ayudarlo a instalar y administrar archivos .d.ts de DefinitelyTyped por usted.

Puede usar módulos normales sin escribir simplemente usando la sintaxis requerida de commonjs normal.

p.ej
var nombre_módulo = require("nombre_módulo")

@chanon se siente como un truco para usar la sintaxis 'clásica' require al usar la sintaxis ES6 con TypeScript para poder usar las dependencias de JavaScript, pero gracias. He oído hablar de la utilidad tsd, pero no estoy seguro de cómo influiría en el uso de las importaciones de ES6... a menos que tenga que empezar a usar /// <reference path=... para este tipo de módulos.

Sí, esa es una manera. Otra forma es usar los archivos tsconfig.json y poner su archivo raíz tsd.d.ts como el primer archivo.

También puede estar interesado en leer esto, cubriendo tsd y escribiendo https://angularclass.com/the-state-of-typescript-packages/

@joewood gracias por la información, la última vez que miré mecanografiado fue en los días de archivos individuales .d.ts . excelente articulo

@chanon @danpantry Es algo desafortunado que import foo = require('foo') (con foo en node_modules) no funcione cuando el archivo package.json de foo no tiene tipos.

@wmono bueno, ya que tal vez la sintaxis de TypeScript 0.80 o anterior import foo = require('foo') era solo para importar módulos con escritura. Si no tuviera tipos, usaría var foo = require('foo') en su lugar. Así que yo diría que es simplemente la forma en que es.

@chanon Perdóname; error de usuario. Parecía que el paquete web estaba luchando con el require "desnudo", pero el problema estaba en otra parte.

Lo siento, ¿alguien puede aclarar por qué?
var foo = require('foo');
Funciona para un node_module estándar sin tipeos pero
import foo from 'foo';
no? ¿Fue eso simplemente definido arbitrariamente? No veo por qué este último _no debería_ funcionar; no me importa si la biblioteca JS externa tiene tipeos o no.

Lo siento, ¿alguien puede aclarar por qué?
var foo = require('foo');
Funciona para un node_module estándar sin tipeos pero
importar foo desde 'foo';
no? ¿Fue eso simplemente definido arbitrariamente? No veo por qué este último no debería funcionar; no me importa si la biblioteca JS externa tiene tipeos o no.

@harangue porque var require era una de las sintaxis de módulos de la competencia (esta es commonjs y otras en la lista incluyen amd ) que se admitía _fuera del sistema de verificación de tipos_. Si uno quiere usar el sistema de tipos, haría import require . Con ES6 tomando el :martillo: y diciendo que una sintaxis (:anillo:) para gobernarlos a todos... tiene sentido que la sintaxis del módulo sea compatible con el sistema de verificación de tipos listo para usar :rose:

@basarat Gracias por la aclaración. Los íconos también fueron útiles. ;) Todavía no estoy seguro de por qué la sintaxis de ES6 exige la verificación de tipos. ¿Qué impide que el compilador diga: "Oh, no pude encontrar ningún tipo de datos para ese módulo, pero lo importaré de todos modos". ¿En qué efectos secundarios incurriría este comportamiento (más bien intuitivo, en mi opinión)?

Esto es confuso para aquellos (como yo) que vienen de ES6 a TypeScript. Espero que la sintaxis de importación del módulo ES6 se comporte de la misma manera en TypeScript, pero lamentablemente no funciona para la mayoría de los paquetes npm...

pero, lamentablemente, no funciona en absoluto para la mayoría de los paquetes npm ...

@teohhanhui Estoy confundido. ¿Puede dar un ejemplo concreto de lo que está tratando de lograr y qué código intentó lograr? Esto es solo para poder ayudarte :rose:

import koa from 'koa';

da Cannot find module 'koa'. (2307) cuando target es es6

koa está (por supuesto) en node_modules

Sin embargo, koa no publica mecanografiados con su proyecto. Esto es solo para paquetes que publican un .d.ts con su proyecto y lo enumeran en su paquete.json. Debido a que koa no lo hace, querrá instalar adicionalmente esas definiciones de tipo de Definitely Typed.

Eso parece una mala decisión, ya que uno esperaría que la declaración import funcione como lo hace en los módulos ES6 simples. (Sí, lo sé, la mayoría de los paquetes npm son módulos CommonJS, pero admitirlos aquí sería lo más sensato).

Soy nuevo en TypeScript, por lo que probablemente tenga una comprensión incorrecta, pero ¿las definiciones de tipo no son opcionales? ¿Por qué no puedo importar el paquete sin la definición de tipo? No quiero verme obligado a buscar/crear definiciones de tipo.

Cambiar a la sintaxis de importación del módulo TS heredado no es una opción porque no está permitido cuando se usa el destino es6 .

Soy nuevo en TypeScript, por lo que probablemente tenga una comprensión incorrecta, pero ¿las definiciones de tipo no son opcionales?

Eso es incorrecto. Las definiciones de tipo _en su propio código_ pueden ser implícitas, lo que significa que el compilador de TypeScript "lo resolverá". Nunca pasará una biblioteca de terceros a través del compilador de TypeScript, por lo que el compilador nunca sabe cuáles son esos tipos. Si planea usar código de terceros, realmente debería aprender a usar Definitely Typed y la herramienta tsd .

¿Qué pasa con esta respuesta de @basarat?

http://stackoverflow.com/a/27434010/1529493

¿Por qué los módulos que no son TypeScript sin definiciones de tipo no se pueden importar como tales?

Pueden: const koa = require(‘koa’)

El 21 de enero de 2016, a las 14:47, Teoh Han Hui [email protected] escribió:

¿Por qué no se pueden importar módulos sin definiciones de tipo como tales?


Responda a este correo electrónico directamente o véalo en GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

@bgrieder Me refiero a la sintaxis de importación de ES6.

(es decir, está usando commonjs), si no, use la respuesta declare var de Basarat

El 21 ene 2016, a las 14:48, Bruno Grieder bruno. [email protected] escribió:

Pueden: const koa = require(‘koa’)

El 21 de enero de 2016, a las 14:47, Teoh Han Hui < [email protected] [email protected] > escribió:

¿Por qué no se pueden importar módulos sin definiciones de tipo como tales?


Responda a este correo electrónico directamente o véalo en GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

Creo que el punto que se está destacando es que uno de los objetivos de TypeScript es que JS válido debería ser TS válido. Para la sintaxis del módulo ES6, TS debe compilar esto con o sin la presencia de declaraciones de tipo. Sin declaraciones de tipo, una instrucción import simplemente debería resolverse en any .

Estoy totalmente de acuerdo con eso.

@Joe Madera 👍

El 21 de enero de 2016, a las 14:52, Joe Wood [email protected] escribió:

Creo que el punto que se está destacando es que uno de los objetivos de TypeScript es que JS válido debería ser TS válido. Para la sintaxis del módulo ES6, TS debe compilar esto con o sin la presencia de declaraciones de tipo. Sin declaraciones de tipo, una declaración de importación debería resolverse en cualquiera.

Estoy totalmente de acuerdo con eso.


Responda a este correo electrónico directamente o véalo en GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173575301.

FWIW, este comportamiento (esperar que todas las bibliotecas de terceros se escriban antes de tiempo) es lo que me hace usar Flow over TypeScript. Si bien TypeScript es compatible con IDE, esperar que todo se escriba antes de tiempo no es realmente razonable, especialmente cuando hay muchas bibliotecas que:

  • No están en DefinitelyTyped
  • No tengo una carpeta ./typings
  • No tengo tiempo para escribirlo yo mismo

Preferiría no tener que luchar contra algo que está destinado a ayudar a mi desarrollo.

@danpantry , ¿por qué no simplemente declarar su punto de entrada de lib como cualquiera, y el compilador se contentará con eso?

declare var $: any;

Esa es una solución. Pero creo que sería una buena idea que TypeScript respetara el código del módulo ES6 y retrocediera con elegancia. No veo una buena razón por la que una declaración de importación no pueda recurrir a any en lugar de informar un error si el módulo de nivel superior no está tipificado.

Preferiría que el compilador fallara pronto y con fuerza (el comportamiento actual), en lugar de permitir que los problemas de tiempo de ejecución pasen desapercibidos. Preferiría tener explícitamente una línea declare var foo: any para indicar "esto no es seguro y sé lo que estoy haciendo".

¿Por qué no simplemente permitir la sintaxis de importación de ES6 cuando no hay tipeos disponibles y emitir un simple compilador que advierte que la importación se resolvió en any , en lugar de un error de «emisión de prevención»?

El 21 de enero de 2016, a las 18:42, S. Chris Colbert [email protected] escribió:

Preferiría que el compilador fallara pronto y con fuerza (el comportamiento actual), en lugar de permitir que los problemas de tiempo de ejecución pasen desapercibidos. Preferiría tener explícitamente una declaración var foo: cualquier línea para indicar "esto no es seguro y sé lo que estoy haciendo".


Responda a este correo electrónico directamente o véalo en GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173649845.

En cualquier caso, el compilador afirma actualmente que no puede encontrar el módulo, cuando en realidad simplemente se niega a importar el módulo sin una definición de tipo. Eso no es realmente útil, ¿verdad?

^^^ Esto mil veces. No había indicios de que estuviera haciendo algo mal cuando me encontré con este problema por primera vez. Tomó mucho tiempo buscar en Google para finalmente descubrir qué estaba pasando (por cierto, creo que este problema es uno de los únicos lugares que lo documentan). Es tan innecesario. Y con Angular 2 trayendo TypeScript más a la corriente principal, solo puedo imaginar cuántas preguntas de desbordamiento de pila surgirán de este comportamiento.

Muy de acuerdo con la descripción deficiente del manejo de errores y simplemente hágalo importar como cualquiera.

@sccolbert Estoy de acuerdo en que debería haber una notificación, pero no estoy seguro de que deba ser una falla; en cambio, quizás sea una advertencia

Estoy de acuerdo con @mhegazy y @sccolbert.

Preferiría que nuestros scripts de compilación de producción (es decir, el servidor CI) se quejen en voz alta si algo anda mal.

Hola tios,
Este comportamiento me vuelve loco. Los archivos de definición no están actualizados o no están registrados en package.json .
Al final TypeScript produce JavaScript , así que, hasta que todos vayamos a este idioma, por favor sea amable con el resto del mundo que proporciona bibliotecas para la lengua materna en cualquier otro idioma transpilado, como el suyo. .
Realmente quiero saber si TypeScript quiere quedarse (diría "integrarse" ya que parece que aún no está allí) en el ecosistema JavaScript o quiere vivir una vida aparte, como la segunda opción me hará ir a otra cosa.
Para lograrlo, bastará con un cambio en el archivo .tsconfig , por lo que podemos decir que queremos importaciones estrictas o no.
En cuanto a la queja fuerte de CI, hay marcos de prueba para eso en JavaScript . De todos modos, no obtendrá verificación de tipo en tiempo de ejecución, la verificación de importación deficiente es el problema menos importante que debe tener.
Todo lo mejor.

@devel-pa, los errores están destinados a decirle que el compilador no tiene idea de cuál es su importación. cualquier uso posterior de la importación no se puede comprobar.

Desactivar los errores no resuelve ningún problema. simplemente empuja estos "desconocidos" silenciosamente a través de su sistema. sin información de tipo, el compilador no puede advertirle sobre lo que es seguro y lo que no. y ese es el objetivo de TypeScript :)

En cuanto a JS generado. ninguno de los errores de tipo TS impide que se genere su salida. si no le importan los errores tipográficos, simplemente ignórelos a todos. el compilador aún genera sus archivos .js correspondientes.

La solución para las definiciones faltantes es declararlas. no es necesario que se declare la forma completa del módulo, sino solo el nombre. Esto permite que el compilador sepa que hay un módulo "myLibrary", puede advertirle sobre errores tipográficos en los nombres de los módulos y, lo que es más importante, ningún otro módulo quedará sin marcar.

declare module "myLibrary" {
    var a: any;
    export = a;
}

como se describe en # 6615, TypeScript debería admitir una forma más corta de esto pronto.

Creo que el problema es el dolor que esto causa para los proyectos de incorporación. Creo que este problema es análogo a implícito any . En este momento, estas importaciones son esencialmente nulas implícitas . Claro, los errores se pueden ignorar, pero eso causa mucho ruido y va en contra de la filosofía de escritura gradual y JS válido es TS válido.

Puedo entender la confusión aquí para las personas nuevas en TS. Si han utilizado activamente la sintaxis del módulo ES6 en JS, ¿por qué no funciona solo en TS? ¿Qué tiene de especial import from sobre var x = require - que _es_ tratado como un cualquiera implícito? Importar originalmente era una palabra clave específica de TS, por lo que implicaba que el desarrollador quería que el módulo se tratara como un módulo con tipo. Ahora que no es exclusivo de TS, no creo que se pueda hacer esa suposición.

los errores implícitos están en declaraciones de variables sin un tipo. pero usar una variable no declarada sigue siendo un error hoy. Para jquery, aún necesita declare var $; en algún lugar para que el compilador sepa que realmente quería tener una variable global llamada $ y no simplemente escribirla mal. es más o menos lo mismo para los módulos, el compilador necesita saber que hay un módulo llamado "myLibrary" y que no es un nombre mal escrito. así que solo agregue una declaración para ello.

en cualquier caso, #6615 debería admitir la adición declare module "*"; para que coincida con todos los módulos de su sistema, aunque creo que si hace eso, no obtendrá ninguna ayuda de sus herramientas, y se está preparando para un doloroso transición más adelante cuando decida eliminarlo.

@mhegazy entiendo tu razonamiento pero realmente tengo un problema con este razonamiento

Básicamente, nos está diciendo que diseñemos una definición de módulo de "marcador de posición" y el problema desaparecerá.
Este riesgo es que después de un tiempo, en un proyecto de tamaño razonable, estas definiciones de "marcador de posición" pueden aparecer y quedar enterradas en algún directorio de escritura. Al no tener más advertencias, todos simplemente se olvidarán de ellas y cuando surja un problema, revisar cada definición de módulo para ver cuál es un marcador de posición, será un dolor de cabeza.

La situación es aún peor con los módulos escritos (los que tienen la entrada typings en package.json) que suponemos que están escritos correctamente y que en realidad podrían estar usando esos marcadores de posición internamente.

Entiendo que estos marcadores de posición no se pueden evitar, pero preferiría que, al menos, no se fomenten.
Lo que se debe recomendar es que, de manera predeterminada, la importación se resuelva en any y que el compilador emita una advertencia en cada compilación. Entonces, al menos, mirando los registros del compilador/CI, sabemos que algo es potencialmente sospechoso y debe mejorarse.

(como un lado no, como se indica en la página de inicio de typescriptlang.org, Typescript es un 'superconjunto' de Javascript, y en mi humilde opinión, cualquier sintaxis válida de ES6 debe tragarse tal como está)

Para mí, las soluciones alternativas y esconder la basura debajo de la alfombra son lo peor que puede pasar (además de ES6 super).
Estoy trabajando con JS libs todo el tiempo y, por lo general, con las últimas versiones como parte de mi trabajo y codificación adicional en casa. El 90% no está escrito o tiene definiciones antiguas, el 9% no está muy bien escrito (ya que el compilador no sabe cómo hacer una definición para todos los archivos). Tampoco los míos tienen muy buenas definiciones, por lo mismo anterior y por el hecho de que mi target es JS, no creo que me tenga que preocupar el idioma original.
Además, he visto la razón por la que hay librerías 'desconocidas'. No, para nada, si los desarrolladores no saben ni entienden qué bibliotecas se usan, ¿por qué molestarse con ellas? Sé por qué estoy usando cosas y por qué las estoy agregando a la pila. Advertencia y pruebas (en caso de que exista) son suficientes para eso.
Por favor, JavaScript primero, este es el objetivo y el ecosistema. TS es solo un accesorio para una mejor codificación y verificación de tipos en tiempo de compilación, pero solo para lo que estamos construyendo. El resto no es asunto de mecanografiados.
Quiero mencionar que yo también estaba en contra de nmps peerDependencies , fui yo quien eligió, no el software. Programación imperativa, cariño.

¿Qué pasa con la importación de módulos desde el directorio JSPM en lugar de node_modules?

editar: encontré un ticket existente -> https://github.com/Microsoft/TypeScript/issues/6012

Acabo de encontrarme con un problema con la resolución del módulo Node, cuando uso SystemJS para cargar un directorio:

Aparentemente, aunque Node (y, por lo tanto, TypeScript) entiende que la ruta es en realidad un directorio y, por lo tanto, carga index.ts en su lugar, SystemJS no hace tal cosa, lo que significa que el código TS válido en realidad no se cargará en el navegador.

Esto también se aplica a los módulos de nodo que tienen un punto de entrada index.ts/js o incluso usan la propiedad package.json main . Es un poco más fácil trabajar con esto, porque es fácil (aunque repetitivo) agregar una configuración de paquete a SystemJS. Esto no es tan fácil cuando se trabaja con directorios arbitrarios.

¿Cuál es la solución adecuada para esto?

La resolución automática del módulo JSPM no se admite actualmente. esto es rastreado por https://github.com/Microsoft/TypeScript/issues/6012.

La recomendación es utilizar la compatibilidad con la resolución del módulo de mapeo de rutas, consulte https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path -mapping

Las instrucciones anteriores son un comienzo, pero es posible que algunas personas necesiten hacer algo adicional... Es posible que deba agregar
<Folder Include="node_modules" />
a .njsproj

Más información

Estaba construyendo con trago y tenía TypeScriptCompileBlocked en .nsproj. Para solucionar problemas en la depuración de puntos de interrupción en VS 15 Preview 5 (obtuve el error "frame not in module") y problemas que tenía con intellisense, tuve que agregar a .njsproj . Ese directorio ya estaba allí cuando importé el proyecto, pero estaba configurado en git-ignore. Esa es mi teoría sobre por qué Visual Studio lo ignoró (¿quizás debería tener una excepción automática para node_modules?)

Más allá de la depuración y el funcionamiento de intellisense, también dejé de ver errores de intellisense más allá de los mismos errores que vi en gulp mientras se construía, lo cual era de esperar.

¿Fue útil esta página
0 / 5 - 0 calificaciones