Comment moment.js peut-il être importé avec dactylographié?

93

J'essaye d'apprendre Typescript. Bien que je ne pense pas que ce soit pertinent, j'utilise VSCode pour cette démo.

J'ai un package.jsonqui contient ces pièces:

{
  "devDependencies": {
    "gulp": "^3.9.1",
    "jspm": "^0.16.33",
    "typescript": "^1.8.10"
  },
  "jspm": {
    "moment": "npm:moment@^2.12.0"
  }
}

Ensuite, j'ai une classe Typescript main.jscomme celle-ci:

import moment from 'moment';
export class Main {
}

Mon gulpfile.jsressemble à ceci:

var gulp = require('gulp');
var typescript = require('gulp-tsb');
var compilerOptions = {
                        "rootDir": "src/",
                        "sourceMap": true,
                        "target": "es5",
                        "module": "amd",
                        "declaration": false,
                        "noImplicitAny": false,
                        "noResolve": true,
                        "removeComments": true,
                        "noLib": false,
                        "emitDecoratorMetadata": true,
                        "experimentalDecorators": true
                      };
var typescriptCompiler = typescript.create(compilerOptions);
gulp.task('build', function() {
  return gulp.src('/src')
    .pipe(typescriptCompiler())
    .pipe(gulp.dest('/dest'));
});

Quand je lance gulp build, je reçois le message: "../main.ts(1,25): Cannot file module 'moment'."

Si j'utilise import moment = require('moment');alors jspm fonctionnera et apportera le module lorsque j'exécute l'application, mais je reçois toujours l'erreur de construction. J'ai aussi essayé:

npm install typings -g
typings install moment --ambient --save

Au lieu d’améliorer le problème, il s’est aggravé. Maintenant, j'obtiens l'erreur ci-dessus lors de la construction ainsi que les éléments suivants:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Si je vais dans le fichier fourni par les saisies et ajoute en bas du fichier:

declare module "moment" { export = moment; }

Je peux faire disparaître la deuxième erreur, mais j'ai toujours besoin de l'instruction require pour obtenir le moment de travailler dans mon main.tsfichier et j'obtiens toujours la première erreur de construction.

Dois-je créer mon propre .d.tsfichier pour le moment ou y a-t-il juste un élément de configuration qui me manque?

développement de peinearyde
la source
Ajout de cette mise à jour pour toute personne qui rencontre cela maintenant: import moment, { Moment } from 'moment';vous permet de faire const x = moment();etconst x: Moment = moment();
ryuu9187
Aucune de ces solutions n'a fonctionné, j'ai déménagé ici - github.com/date-fns/date-fns
chrismarx

Réponses:

120

Mettre à jour

Apparemment, moment fournit maintenant ses propres définitions de type (selon sivabudh au moins à partir de 2.14.1), donc vous n'avez pas besoin typingsou pas @typesdu tout.

import * as moment from 'moment' devrait charger les définitions de type fournies avec le package npm.

Cela dit cependant, comme indiqué dans moment / pull / 3319 # issuecomment-263752265, l'équipe du moment semble avoir des problèmes pour maintenir ces définitions (elle cherche toujours quelqu'un qui les maintient) .


Vous devez installer des momenttypages sans le--ambient indicateur.

Puis incluez-le en utilisant import * as moment from 'moment'

Aides
la source
Ça a marché. Pouvez-vous expliquer la différence entre utiliser le --ambientdrapeau et non? J'ai fait fonctionner numeraljs en utilisant le drapeau ambiant. De plus, leur page principale npmjs.com/package/typings donne l'exemple en utilisant l'indicateur ambient. Je ne sais pas quand je voudrais / devrais utiliser l'un sur l'autre. Merci!
peinearydevelopment
1
Pour être honnête, je ne peux pas. Normalement, vous utilisez l' --ambientindicateur pour toutes les définitions Typescript de typings/ DefinitelyTypedmais la momentdéfinition a une structure étrange et les fichiers ne sont pas téléchargés correctement. Si vous regardez le fichier de définition moment.d.ts, il ne contient qu'une référence à la version du nœud, qui n'est pas résolue lors du téléchargement (cela peut valoir la peine d'ouvrir un problème).
Aides
Apparemment, il y en a déjà un lié à ce problème: github.com/DefinitelyTyped/DefinatelyTyped/issues/8388
peinearydevelopment
1
Je l'ai fait fonctionner en utilisant import * comme moment à partir de «moment / moment» car il a été installé en tant que sous-dossier dans le dossier node-modules.
user441058
1
Je suis sur un webpack, et moment version 2.17.1 mais je n'arrive toujours pas à le faire fonctionner. J'ai essayé: importer * comme moment à partir de «moment»; et importez * comme moment à partir de «moment / moment»; et ne fonctionne pas!
Mohy Eldeen le
58

Vous devez importer moment () la fonction et Moment la classe séparément dans TS.

J'ai trouvé une note dans la documentation dactylographiée ici .

/ * ~ Notez que les modules ES6 ne peuvent pas exporter directement les fonctions appelables
* ~ Ce fichier doit être importé en utilisant le style CommonJS:
* ~ import x = require ('someLibrary');

Ainsi, le code pour importer moment js dans un script dactylographié ressemble en fait à ceci:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Koby
la source
1
Bonne réponse car elle montre la différence entre le type et la fonction. Merci!
Jelle
impossible de trouver le nom 'require'
Conteneur codé
4
Maintenant, cela peut être utilisé au fur import * as moment from 'moment';et moment.Momentà mesure des saisies.
meteor
Ce qui a fonctionné pour moi était: import moment = require ('moment');
Telmo Pimentel Mota
En fait, vous pouvez également utiliser l' moment.Momentinterface directement à partir de l'espace de nomsmoment
HalfWebDev
19

Je ne sais pas quand cela a changé, mais avec la dernière version de tapuscript, il vous suffit d'utiliser import moment from 'moment'; et tout le reste devrait fonctionner normalement.

METTRE À JOUR:

On dirait que le moment récent a corrigé leur importation. Au moins, 2.24.0vous voudrez utiliserimport * as moment from 'moment';

NSjonas
la source
5
import * as moment from 'moment'ne fonctionnera pas avec dactylographié mais le import moment from 'moment'fait.
Stuart McIntyre
Cela fonctionne mais j'obtiens l'heure GMT 0, mais j'ai besoin de l'heure locale qui ne fonctionne pas. J'essaie aussi avec moment (). Utc (). Format () mais il retient le même résultat.
kbhaskar
@kbhaskar à partir de la dernière version du moment, ils ont corrigé leur importation. Voir la réponse mise à jour
NSjonas
1
Je pense que c'est à peu près tout. La seule étape supplémentaire que je devais faire était d'ajouter un esModuleInteropensemble truedans ma configuration, ce que j'ai obtenu de cette réponse . Merci.
Mark Birbeck
14

via des typages

Moment.js prend désormais en charge TypeScript dans la v2.14.1.

Voir: https://github.com/moment/moment/pull/3280


Directement

Ce n'est peut-être pas la meilleure réponse, mais c'est la méthode de la force brute, et cela fonctionne pour moi.

  1. Téléchargez simplement le moment.jsfichier réel et incluez-le dans votre projet.
  2. Par exemple, mon projet ressemble à ceci:

$ tree . ├── main.js ├── main.js.map ├── main.ts └── moment.js

  1. Et voici un exemple de code source:

''

import * as moment from 'moment';

class HelloWorld {
    public hello(input:string):string {
        if (input === '') {
            return "Hello, World!";
        }
        else {
            return "Hello, " + input + "!";
        }
    }
}

let h = new HelloWorld();
console.log(moment().format('YYYY-MM-DD HH:mm:ss'));
  1. Utilisez juste nodepour courir main.js.
sivabudh
la source
Oui, je confirme que c'est la bonne réponse. A travaillé comme un charme.
Capy
Lorsque j'essaie de le faire en utilisant npm i @ types / moment, je reçois une erreur: Erreur TypeScript: src \ app.ts (1,1): erreur TS7038: Une importation de style espace de nom ne peut pas être appelée ou construite, et provoquera un échec à l'exécution. sur tsc -v 2.7.2
GONeale
1

Je viens de remarquer que la réponse sur laquelle j'ai voté et commenté est ambiguë. Voici donc exactement ce qui a fonctionné pour moi. Je suis actuellement sur Moment 2.26.0et TS3.8.3 :

Dans du code:

import moment from 'moment';

Dans la configuration TS:

{
  "compilerOptions": {
    "esModuleInterop": true,
    ...
  }
}

Je construis à la fois pour CommonJS et EMS, donc cette configuration est importée dans d'autres fichiers de configuration.

La perspicacité vient de cette réponse qui concerne l'utilisation d'Express. J'ai pensé que cela valait la peine d'ajouter ici, pour aider tous ceux qui recherchent en relation avec Moment.js, plutôt que quelque chose de plus général.

Mark Birbeck
la source
alors vous pouvez utiliser moment()comme d'habitude au lieu demoment.default()
xinthose
0

1. installez le moment

npm install moment --save

2. testez ce code dans votre fichier dactylographié

import moment = require('moment');

console.log(moment().format('LLLL'));
lutula rustique
la source
1
Ce n'est pas la bonne façon d'importer un module au format dactylographié. Veuillez envisager de mettre à jour votre réponse. Référez-vous à ceci pour confirmation: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

Encore cassé? Essayez de désinstaller @types/moment.

Donc, j'ai supprimé le @types/momentpackage du package.jsonfichier et cela a fonctionné en utilisant:

import * as moment from 'moment'

Les nouvelles versions de momentne nécessitent pas le @types/momentpackage car les types sont déjà inclus.

Ben Winding
la source