react example typescript npm typescript-typings

example - typescript react



TypeScript 2: tipificaciones personalizadas para módulo npm sin tipo (4)

Después de probar las sugerencias publicadas en otros lugares , no puedo ejecutar un proyecto mecanografiado que utiliza un módulo NPM sin tipo. A continuación se muestra un ejemplo mínimo y los pasos que probé.

Para este ejemplo mínimo, pretendemos que lodash no tiene definiciones de tipo existentes. Como tal, ignoraremos el paquete @types/lodash e intentaremos agregar manualmente su archivo de lodash.d.ts a nuestro proyecto.

Estructura de carpetas

  • nodo_módulos
    • lodash
  • src
    • foo.ts
  • tipings
    • personalizado
      • lodash.d.ts
    • global
    • index.d.ts
  • package.json
  • tsconfig.json
  • typings.json

A continuación, los archivos.

Archivo foo.ts

///<reference path="../typings/custom/lodash.d.ts" /> import * as lodash from ''lodash''; console.log(''Weeee'');

El archivo lodash.d.ts se copia directamente del paquete original @types/lodash .

Archivo index.d.ts

/// <reference path="custom/lodash.d.ts" /> /// <reference path="globals/lodash/index.d.ts" />

Archivo package.json

{ "name": "ts", "version": "1.0.0", "description": "", "main": "index.js", "typings": "./typings/index.d.ts", "dependencies": { "lodash": "^4.16.4" }, "author": "", "license": "ISC" }

Archivo tsconfig.json

{ "compilerOptions": { "target": "ES6", "jsx": "react", "module": "commonjs", "sourceMap": true, "noImplicitAny": true, "experimentalDecorators": true, "typeRoots" : ["./typings"], "types": ["lodash"] }, "include": [ "typings/**/*", "src/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts" ] }

Archivo typings.json

{ "name": "TestName", "version": false, "globalDependencies": { "lodash": "file:typings/custom/lodash.d.ts" } }

Como puede ver, he probado muchas formas diferentes de importar tipings:

  1. foo.ts directamente en foo.ts
  2. Por una propiedad de typings en package.json
  3. Al usar typeRoots en tsconfig.json con un archivo typings/index.d.ts
  4. Mediante el uso de types explícitos en tsconfig.json
  5. Al incluir el directorio de types en tsconfig.json
  6. Al hacer un archivo typings.json personalizado y ejecutar typings install

Sin embargo, cuando ejecuto Typecript:

E:/temp/ts>tsc error TS2688: Cannot find type definition file for ''lodash''.

¿Qué estoy haciendo mal?


Desafortunadamente, estas cosas actualmente no están muy bien documentadas, pero incluso si pudo hacer que funcionara, repasemos su configuración para que comprenda qué está haciendo cada parte y cómo se relaciona con la forma en que los procesos mecanografiados y las tipificaciones de carga.

Primero repasemos el error que está recibiendo:

error TS2688: Cannot find type definition file for ''lodash''.

Este error en realidad no proviene de sus importaciones o referencias o su intento de usar lodash en cualquier parte de sus archivos ts. Más bien proviene de un malentendido sobre cómo usar las propiedades typeRoots y types , así que entremos un poco más en detalle sobre ellas.

Lo que pasa con las typeRoots:[] y types:[] es que NO son formas de uso general para cargar archivos de declaración arbitraria ( *.d.ts ).

Estas dos propiedades están directamente relacionadas con la nueva característica TS 2.0 que permite empaquetar y cargar declaraciones de tipado de paquetes NPM .

Es muy importante comprender que funcionan solo con carpetas en formato NPM (es decir, una carpeta que contiene un paquete.json o index.d.ts ).

El valor predeterminado para typeRoots es:

{ "typeRoots" : ["node_modules/@types"] }

De manera predeterminada, esto significa que el mecanografiado irá a la carpeta node_modules/@types e intentará cargar cada subcarpeta que encuentre allí como un paquete npm .

Es importante comprender que esto fallará si una carpeta no tiene una estructura similar a un paquete npm.

Esto es lo que está sucediendo en su caso, y la fuente de su error inicial.

Ha cambiado typeRoot para ser:

{ "typeRoots" : ["./typings"] }

Esto significa que el mecanografiado ahora escaneará la carpeta ./typings busca de subcarpetas e intentará cargar cada subcarpeta que encuentre como un módulo npm.

Supongamos que acaba de configurar typeRoots para apuntar a ./typings pero aún no tenía ningún types:[] configuración de propiedad. Es probable que vea estos errores:

error TS2688: Cannot find type definition file for ''custom''. error TS2688: Cannot find type definition file for ''global''.

Esto se debe a que tsc está escaneando su carpeta ./typings y buscando las subcarpetas custom y global . Luego está tratando de interpretarlos como tipeo tipo paquete npm, pero no hay index.d.ts o package.json en estas carpetas, por lo que obtiene el error.

Ahora hablemos un poco sobre los types: [''lodash''] propiedad types: [''lodash''] que está configurando. ¿Qué hace esto? Por defecto, mecanografiado cargará todas las subcarpetas que encuentre dentro de sus typeRoots . Si especifica una propiedad types: solo cargará esas subcarpetas específicas.

En su caso, le está diciendo que cargue la carpeta ./typings/lodash pero no existe. Es por eso que obtienes:

error TS2688: Cannot find type definition file for ''lodash''

Así que resumamos lo que hemos aprendido. TypeScript 2.0 introdujo typeRoots y types para cargar archivos de declaración empaquetados en paquetes npm . Si tiene tipificaciones personalizadas o archivos d.ts sueltos que no están contenidos dentro de una carpeta siguiendo las convenciones del paquete npm, entonces estas dos nuevas propiedades no son lo que desea usar. Typecript 2.0 realmente no cambia cómo se consumirían. Solo tiene que incluir estos archivos en su contexto de compilación de una de las muchas formas estándar:

  1. .ts directamente en un archivo .ts : ///<reference path="../typings/custom/lodash.d.ts" />

  2. Incluyendo ./typings/custom/lodash.d.ts en sus files: [] propiedad files: [] .

  3. Incluyendo ./typings/index.d.ts en sus files: [] propiedad files: [] (que luego incluye recursivamente los otros tipos).

  4. Agregar ./typings/** a su includes:

Con suerte, en base a esta discusión, podrá decir por qué los cambios que le tsconfig.json a su tsconfig.json hicieron que las cosas volvieran a funcionar.

EDITAR:

Una cosa que olvidé mencionar es que las propiedades typeRoots y types realmente solo son útiles para la carga automática de declaraciones globales.

Por ejemplo si tu

npm install @types/jquery

Y está utilizando el tsconfig predeterminado, entonces ese paquete de tipos jquery se cargará automáticamente y $ estará disponible en todos sus scripts sin tener que hacer más ///<reference/> o import

La typeRoots:[] está destinada a agregar ubicaciones adicionales desde donde los paquetes de tipo se cargarán automáticamente.

Los types:[] el caso de uso principal de la propiedad types:[] es deshabilitar el comportamiento de carga automática (configurándolo en una matriz vacía) y luego solo enumerar los tipos específicos que desea incluir globalmente.

La otra forma de cargar paquetes de tipos desde los distintos typeRoots es usar la nueva directiva ///<reference types="jquery" /> . Observe los types lugar de la path . Nuevamente, esto solo es útil para los archivos de declaración global, generalmente aquellos que no import/export .

Ahora, aquí está una de las cosas que causa confusión con typeRoots . Recuerde, dije que typeRoots se trata de la inclusión global de módulos. Pero @types/folder también está involucrado en la resolución estándar del módulo (independientemente de la configuración de typeRoots ).

Específicamente, la importación explícita de módulos siempre omite todas las opciones de includes , excludes , files , typeRoots y typeRoots . Entonces cuando lo haces:

import {MyType} from ''my-module'';

Todas las propiedades mencionadas anteriormente se ignoran por completo. Las propiedades relevantes durante la resolución del módulo son baseUrl , paths y moduleResolution .

Básicamente, cuando se utiliza la resolución del módulo de node , comenzará a buscar un nombre de archivo my-module.ts , my-module.tsx , my-module.d.ts comenzando en la carpeta señalada por su configuración baseUrl .

Si no encuentra el archivo, buscará una carpeta llamada my-module y luego buscará un package.json con una propiedad de typings , si hay package.json o no hay typings propiedad de typings dentro que le typings qué archivo cargar luego buscará index.ts/tsx/d.ts dentro de esa carpeta.

Si todavía no tiene éxito, buscará estas mismas cosas en la carpeta node_modules comenzando en su baseUrl/node_modules .

Además, si no encuentra estos, buscará los baseUrl/node_modules/@types para todas las mismas cosas.

Si todavía no encuentra nada, comenzará a ir al directorio principal y buscará node_modules y node_modules/@types allí. Seguirá subiendo los directorios hasta que llegue a la raíz de su sistema de archivos (incluso obteniendo módulos de nodo fuera de su proyecto).

Una cosa que quiero enfatizar es que la resolución del módulo ignora completamente cualquier tipo de typeRoots que establezca. Entonces, si configuró typeRoots: ["./my-types"] , esto no se buscará durante la resolución explícita del módulo. Solo sirve como una carpeta donde puede colocar archivos de definición global que desee poner a disposición de toda la aplicación sin necesidad de importar o hacer referencia.

Por último, puede anular el comportamiento del módulo con asignaciones de ruta (es decir, la propiedad de paths ). Entonces, por ejemplo, mencioné que no se consulta ningún typeRoots personalizado al intentar resolver un módulo. Pero si te gustó puedes hacer que este comportamiento suceda así:

"paths" :{ "*": ["my-custom-types/*", "*"] }

Lo que esto hace es para todas las importaciones que coinciden con el lado izquierdo, intente modificar la importación como en el lado derecho antes de intentar incluirla (el * en el lado derecho representa su cadena de importación inicial. Por ejemplo, si importa:

import {MyType} from ''my-types'';

Primero intentaría importar como si hubiera escrito:

import {MyType} from ''my-custom-types/my-types''

Y luego, si no lo encuentra, lo intentará nuevamente sin el prefijo (el segundo elemento de la matriz es solo * que significa la importación inicial.

De esta forma, puede agregar carpetas adicionales para buscar archivos de declaración personalizados o incluso módulos .ts personalizados que desee poder import .

También puede crear asignaciones personalizadas para módulos específicos:

"paths" :{ "*": ["my-types", "some/custom/folder/location/my-awesome-types-file"] }

Esto te dejaría hacer

import {MyType} from ''my-types'';

Pero luego lea esos tipos de some/custom/folder/location/my-awesome-types-file.d.ts


Editar: fuera de fecha. Lee la respuesta anterior.

Todavía no entiendo esto, pero encontré una solución. Use el siguiente tsconfig.json :

{ "compilerOptions": { "target": "ES6", "jsx": "react", "module": "commonjs", "sourceMap": true, "noImplicitAny": true, "experimentalDecorators": true, "baseUrl": ".", "paths": { "*": [ "./typings/*" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts" ] }

Elimine typings.json y todo lo que se encuentre debajo de los typings carpeta, excepto lodash.d.ts . También elimine todas las referencias ///...


Sé que esta es una vieja pregunta, pero las herramientas mecanografiadas han cambiado continuamente. Creo que la mejor opción en este punto es confiar en la configuración de ruta "incluir" en tsconfig.json.

"include": [ "src/**/*" ],

De manera predeterminada, a menos que realice cambios particulares, todos los archivos * .ts y * .d.ts en src/ incluirán automáticamente. Creo que esta es la forma más fácil / mejor de incluir archivos de declaración de tipo personalizados sin personalizar typeRoots y types .

Referencia:


"*": ["./types/*"] Esta línea en las rutas tsconfig solucionó todo después de 2 horas de lucha.

{ "compilerOptions": { "moduleResolution": "node", "strict": true, "baseUrl": ".", "paths": { "*": ["./types/*"] }, "jsx": "react", "types": ["node", "jest"] }, "include": [ "client/**/*", "packages/**/*" ], "exclude": [ "node_modules/**/*" ] }

tipos es el nombre de la carpeta, que se encuentra junto a node_module, es decir, en el nivel de la carpeta del cliente (o carpeta src ) types/third-party-lib/index.d.ts
index.d.ts ha declare module ''third-party-lib'';

Nota: La configuración anterior es una configuración incompleta, solo para dar una idea de cómo se ve con los tipos, rutas, incluir y excluir en ella.