Comment consommer des modules npm à partir de typescript?


91

Je tente une écriture dactylographiée. Cela fonctionne bien sur la scène Hello World. J'essaye maintenant d'utiliser un module npm:

index.ts =

import _ = require('lodash')

console.log(_.toUpper('Hello, world !'))

Cela ne fonctionne pas:

  • tsc index.ts -> Cannot find module 'lodash'. (2307)
  • node-ts index.js -> Cannot find module 'lodash'. (2307)

Regarder la documentation dactylographiée et dans Google n'a pas aidé. D'autres questions S / O sont soit sans réponse ( ici et ici ), soit sans rapport.

Éléments :

  • typescript 1.8 dernier
  • Oui, lodash est installé npm i --save lodashet existe dans mon système de fichiers (coché)
  • J'ai aussi fait typings i --save lodash
  • variantes import * as _ from 'lodash'ou const _ = require('lodash')ne fonctionnent pas non plus
  • J'ai essayé de peaufiner les options tsconfig.json comme suggéré dans d'autres réponses "moduleResolution": "node"et "module": "commonjs"comme suggéré dans certaines réponses, cela ne fonctionne toujours pas

Comment consommer un package npm en typographie ??


2
Avez-vous ajouté une référence à lodash.d.ts dans votre index.ts? Cela devrait ressembler à ceci: ///<reference path="../typings/lodash/lodash.d.ts"/>
Granga

@Granga Cela fonctionne. Pouvez-vous ajouter ceci comme réponse?
Offirmo le

2
Heureux que ça marche. Blackus a déjà ajouté la réponse et elle précise encore mieux ce que j'ai suggéré. Une remarque cependant: lorsque les fichiers d'entrée sont spécifiés sur la ligne de commande (ce qui est votre cas), les fichiers tsconfig.json sont ignorés. ( source )
Granga

Réponses:


61

[EDIT] Merci beaucoup pour cette réponse! Cependant, à partir de 2018, il est obsolète. Lecteurs, jetez un œil aux autres réponses.

Il existe plusieurs façons d'importer des modules depuis npm. Mais si vous n'obtenez pas de dactylographie, tscse plaindra toujours qu'il ne trouve pas le module dont vous avez besoin (même si transpiled js fonctionne réellement ).

  • Si vous avez des typages et n'utilisez pas de tsconfig.json, utilisez referencepour importer les typages:

    /// <reference path="path/to/typings/typings.d.ts" />
    
    import * as _ from 'lodash`;
    
    console.log(_.toUpper('Hello, world !'))
    
  • Si vous utilisez un tsconfig.jsonfichier, assurez-vous que votre fichier de frappe est inclus (ou non exclu, selon votre choix), et procédez importcomme dans l'exemple précédent.

Dans le cas où il n'y a pas de typages disponibles. Vous avez deux choix: écrire le vôtre sur un .d.tsfichier ou ignorer la vérification de type pour la bibliothèque.

Pour ignorer complètement la vérification de type (ce n'est pas la méthode recommandée), importez la bibliothèque sur une variable de type any.

 const _: any = require('lodash');

 console.log(_.toUpper('Hello, world !'))

tscse plaindra qui requiren'existe pas. Fournissez des nodetypages ou declarepour ignorer l'erreur.


2
Réponse complète avec 3 solutions. +1
Offirmo

Ajout: cela fonctionne même avec ts-nodetant que l'index de typages est référencé danstsconfig.json
Offirmo

Je suis confus par ce que vous entendez par «déclarer pour éliminer l'erreur». Dois-je effectuer cette modification dans le module que j'essaie d'importer?
Slug

1
Cette réponse est gravement dépassée. Voir ma nouvelle réponse ci-dessous stackoverflow.com/a/53786892/587407
Offirmo

50

[2018/12] Nouvelle réponse à jour à cette question que j'ai posée en 2016, qui montre toujours beaucoup d'activité malgré des réponses obsolètes.

Pour faire court, TypeScript requiert des informations de type sur le code de votre paquet (aka " fichiers de déclaration de type " ou "typages") et vous indique à juste titre que vous perdriez sinon tout l'intérêt de TypeScript. Il existe plusieurs solutions pour les proposer ou les refuser, répertoriées ici par ordre de bonnes pratiques:


Solution 0 : le module fournit déjà les typages. Si son package.json contient une ligne comme celle-ci:

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

il est déjà compatible avec TypeScript. Ce n'est probablement pas le cas si vous lisez cette page, alors continuons ...


Solution 1 : utilisez les typages fournis par la communauté de DefinitelyTyped . Pour un module "foo", essayez ceci:

npm add -D @types/foo

si ça marche, jackpot! Vous avez maintenant les typages et pouvez utiliser votre module. Si npm se plaint de ne pas trouver le module @ types / foo, continuons ...


Solution 2 : fournissez des typages personnalisés sur ce module. (avec une option pour ne faire aucun effort)

  1. Créez un dossier nommé "typings-custom" à la racine de votre projet
  2. Faites référence au contenu de ce dossier dans votre tsconfig.json:
"include": [
    "./typings-custom/**/*.ts"
]
  1. Créez un fichier avec ce nom exact: foo.d.ts [foo = le nom du module] avec le contenu:
declare module 'foo'

Votre code TypeScript devrait maintenant compiler, mais sans informations de type (TypeScript considère le module foo de type "any").

Vous pouvez également essayer d'écrire vous-même les informations de type, en consultant le document officiel et / ou des exemples de DefinitelyTyped . Si vous le faites, pensez à contribuer vos typages soit directement dans le module (solution 0, si l'auteur du module accepte), soit dans DefinitelyTyped (solution 1)


1
@Offirmo, nous pouvons également déclarer plusieurs typages personnalisés dans un seul fichier! Donc, pas besoin de plusieurs fichiers (peut-être?).
lazycipher

Étape 2. Reference the content of this folder in your tsconfig.json:donne l'erreur suivante: Unknown compiler option 'include'.
Sumit

1
@Sumit ce n'est pas une option du compilateur, il devrait être un frère decompilerOptions
Offirmo

22

Il vous manque probablement les fichiers de déclaration .

Voir DefinatelyTyped pour plus d'informations.


Essaye ça:

npm install --save lodash
npm install --save @types/lodash

Vous pouvez maintenant importer.

import _ from 'lodash';

Si le module que vous importez a plusieurs exportations , vous pouvez le faire:

import { Express, Router } from 'express';

Si le module que vous importez "n'a pas d'export par défaut", vous devez procéder comme suit:

import * as http from 'http';

Pourquoi devons-nous utiliser * as _et pas seulement _ from 'lodash'comme dans le code ES6?
JohnnyQ

@JohnnyQ Bon point. L'utilisation import _ from 'lodash';est meilleure dans ce cas. J'ai mis à jour ma réponse pour montrer différentes manières d'importer et pourquoi vous les utiliseriez.
Derek Soike

1
Le * as _ est nécessaire si le module n'a pas d'export par défaut. Le compilateur tsc vous en avertira.
user2867342

Par "aucune exportation par défaut", cela signifie-t-il qu'aucun type Typecript n'est défini (c'est-à-dire importer un module JavaScript brut)? Je suis nouveau sur JS / Typescript ....
Big Rich

2
@BigRich "Pas d'export par défaut" signifie que le module n'a pas d' export default <...>instruction. Jetez un œil à la section "Exportations par défaut" de la documentation des modules Typescript .
Derek Soike

4

Cela a fonctionné pour moi.

  1. Créez un dossier nommé "typings".
  2. Dans le dossier typings, créez un nom de fichier nom -module.d.ts . Il contient:

    declare module "module-name";

  3. Dans tsconfig.json, reportez-vous au dossier

    "typeRoots": [ "./typings", "../node_modules/@types" ]


Salut! Merci pour votre contribution. Cette méthode est déjà incluse dans ma réponse et ne doit être utilisée qu'en dernier recours.
Offirmo

L'étape 3:, In tsconfig.json, refer to the folderdonne l'erreur suivante:Unknown compiler option 'typesRoots'.
Sumit

1
@Sumit dans mon cas, "typesRoots" est à l'intérieur de "compilerOptions"
Quynh Ngo

1
C'est typeRoots pas typesRoots, et devrait être à l'intérieur de compilerOptions
CM

0

J'ai eu cette erreur et aucune des réponses n'a fonctionné pour moi, mais je trouve quelque chose lorsque vous voulez travailler avec le module de nœud en tapé manuscrit, installez-les comme

$npm install @types/<module_name>

par exemple

npm install @types/cheerio

au lieu de dire

npm install cheerio
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.