Wie kann moment.js mit Typoskript importiert werden?

93

Ich versuche Typoskript zu lernen. Obwohl ich es nicht für relevant halte, verwende ich VSCode für diese Demo.

Ich habe eine package.json, die diese Stücke enthält:

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

Dann habe ich eine Typescript-Klasse main.jswie diese:

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

Mein gulpfile.jssieht so aus:

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'));
});

Wenn ich gulp build starte, erhalte ich die folgende Meldung: "../main.ts(1,25): Cannot file module 'moment'."

Wenn ich verwende, import moment = require('moment');funktioniert jspm und bringt das Modul ein, wenn ich die Anwendung ausführe, aber ich erhalte immer noch den Build-Fehler. Ich habe auch versucht:

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

Anstatt das Problem zu verbessern, wurde es schlimmer. Jetzt erhalte ich den obigen Fehler beim Erstellen sowie den folgenden:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Wenn ich zu der durch Eingaben bereitgestellten Datei gehe und am Ende der Datei hinzufüge:

declare module "moment" { export = moment; }

Ich kann den zweiten Fehler beheben lassen, aber ich benötige immer noch die require-Anweisung, damit der Moment in meiner main.tsDatei funktioniert, und erhalte immer noch den ersten Build-Fehler.

Muss ich .d.tsfür einen Moment meine eigene Datei erstellen oder fehlt mir nur ein Setup-Teil?

peinearydevelopment
quelle
Hinzufügen dieses Updates für alle, die jetzt darauf import moment, { Moment } from 'moment';const x = moment();const x: Moment = moment();
stoßen
Keine dieser Lösungen hat funktioniert, ich bin hierher gezogen - github.com/date-fns/date-fns
chrismarx

Antworten:

118

Aktualisieren

Anscheinend bietet moment jetzt seine eigenen Typdefinitionen (laut sivabudh mindestens ab 2.14.1), sodass Sie diese nicht typingsoder überhaupt nicht benötigen @types.

import * as moment from 'moment' sollte die mit dem npm-Paket gelieferten Typdefinitionen laden.

Das heißt jedoch, wie in moment / pull / 3319 # issuecomment-263752265 gesagt, scheint das Moment-Team einige Probleme bei der Pflege dieser Definitionen zu haben (sie suchen immer noch jemanden, der sie pflegt) .


Sie müssen momentTypisierungen ohne --ambientFlag installieren .

Dann schließen Sie es mit ein import * as moment from 'moment'

Helfer
quelle
Das hat funktioniert. Können Sie den Unterschied zwischen der Verwendung der --ambientFlagge und nicht erklären ? Ich habe Ziffern mit der Umgebungsflagge arbeiten lassen. Die Hauptseite npmjs.com/package/typings enthält das Beispiel unter Verwendung des Umgebungsflags. Ich weiß nicht, wann ich eines über dem anderen verwenden möchte / muss. Vielen Dank!
Peinearydevelopment
1
Um ehrlich zu sein, kann ich nicht. Normalerweise verwenden Sie das --ambientFlag für alle Typoskript-Definitionen von typings/, DefinitelyTypedaber die momentDefinition hat eine seltsame Struktur und die Dateien werden nicht korrekt heruntergeladen. Wenn Sie sich die Definitionsdatei moment.d.ts ansehen , enthält sie nur einen Verweis auf die Knotenversion, die beim Download nicht behoben wird (möglicherweise lohnt es sich, ein Problem zu öffnen).
Helfer
Anscheinend gibt es bereits eine, die sich auf dieses Problem
bezieht
1
Ich habe es mit import * als Moment von 'moment / moment' b / c zum Laufen gebracht. Es wurde als Unterordner im Ordner node-modules installiert.
user441058
1
Ich bin auf einem Webpack und Moment Version 2.17.1, kann es aber immer noch nicht zum Laufen bringen. Ich habe versucht: * als Moment von 'Moment' importieren; und importiere * als Moment von 'Moment / Moment'; und funktioniert nicht!
Mohy Eldeen
58

Sie müssen moment () die Funktion und Moment die Klasse separat in TS importieren .

Ich habe hier einen Hinweis in den Typoskript-Dokumenten gefunden .

/ * ~ Beachten Sie, dass ES6-Module aufrufbare Funktionen nicht direkt exportieren können.
* ~ Diese Datei sollte im CommonJS-Stil importiert werden:
* ~ import x = require ('someLibrary');

Der Code zum Importieren von moment js in Typoskript sieht also tatsächlich so aus:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Koby
quelle
1
Gute Antwort, da es den Unterschied zwischen Typ und Funktion zeigt. Vielen Dank!
Jelle
Name 'require' kann nicht gefunden werden
Codierter Container
4
Dies kann nun als import * as moment from 'moment';und dann moment.Momentfür die Eingabe verwendet werden.
Meteor
Was für mich funktioniert hat war: import moment = require ('moment');
Telmo Pimentel Mota
Eigentlich können Sie die moment.MomentSchnittstelle auch direkt aus dem Namespace verwendenmoment
kushalvm
19

Ich bin mir nicht sicher, wann sich dies geändert hat, aber mit der neuesten Version von Typoskript müssen Sie nur verwenden import moment from 'moment';und alles andere sollte wie gewohnt funktionieren.

AKTUALISIEREN:

Sieht so aus, als ob der Import kürzlich behoben wurde. Ab mindestens 2.24.0möchten Sie verwendenimport * as moment from 'moment';

NSjonas
quelle
5
import * as moment from 'moment'funktioniert nicht mit Typoskript, import moment from 'moment'tut es aber .
Stuart McIntyre
Es funktioniert, aber ich bekomme Zeit für GMT 0, aber ich brauche Ortszeit, die nicht funktioniert. Ich versuche es auch mit moment (). Utc (). Format (), aber es behält das gleiche Ergebnis bei.
kbhaskar
@kbhaskar ab der neuesten Version von Moment haben sie ihren Import behoben. Siehe aktualisierte Antwort
NSjonas
1
Ich denke das ist so ziemlich alles. Der einzige zusätzliche Schritt, den ich tun musste, war das Hinzufügen eines esModuleInteropSatzes truein meiner Konfiguration, den ich aus dieser Antwort erhielt . Vielen Dank.
Mark Birbeck
14

über Typisierungen

Moment.js unterstützt jetzt TypeScript in Version 2.14.1.

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


Direkt

Könnte nicht die beste Antwort sein, aber dies ist der Brute-Force-Weg, und er funktioniert für mich.

  1. Laden Sie einfach die eigentliche moment.jsDatei herunter und fügen Sie sie in Ihr Projekt ein.
  2. Zum Beispiel sieht mein Projekt so aus:

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

  1. Und hier ist ein Beispielquellcode:

`` `

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. Einfach nodezum Laufen verwenden main.js.
Sivabudh
quelle
Ja, ich bestätige, dass dies die richtige Antwort ist. Lief wie am Schnürchen.
Capy
Wenn ich versuche, dies mit npm i @ types / moment zu tun, wird folgende Fehlermeldung angezeigt: TypeScript-Fehler: src \ app.ts (1,1): Fehler TS7038: Ein Import im Namespace-Stil kann nicht aufgerufen oder erstellt werden und verursacht ein Fehler zur Laufzeit. auf tsc -v 2.7.2
GONeale
0

1. Moment installieren

npm install moment --save

2. Testen Sie diesen Code in Ihrer Typoskriptdatei

import moment = require('moment');

console.log(moment().format('LLLL'));
robuste Lutula
quelle
1
Dies ist nicht der richtige Weg, um ein Modul in Typoskript zu importieren. Bitte erwägen Sie, Ihre Antwort zu aktualisieren. Zur Bestätigung siehe dies: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

Ich habe gerade bemerkt, dass die Antwort, die ich positiv bewertet und kommentiert habe, nicht eindeutig ist. Das Folgende ist genau das, was für mich funktioniert hat. Ich bin derzeit auf Moment 2.26.0und TS 3.8.3:

In Code:

import moment from 'moment';

In der TS-Konfiguration:

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

Ich baue sowohl für CommonJS als auch für EMS, sodass diese Konfiguration in andere Konfigurationsdateien importiert wird.

Die Erkenntnis ergibt sich aus dieser Antwort, die sich auf die Verwendung von Express bezieht. Ich dachte, es lohnt sich, hier etwas hinzuzufügen, um jedem zu helfen, der in Bezug auf Moment.js sucht, anstatt etwas allgemeineres.

Mark Birbeck
quelle
0

Immer noch kaputt? Versuchen Sie es zu deinstallieren @types/moment.

Also habe ich das @types/momentPaket aus der package.jsonDatei entfernt und es hat funktioniert mit:

import * as moment from 'moment'

Neuere Versionen von momenterfordern das @types/momentPaket nicht, da Typen bereits enthalten sind.

Ben Winding
quelle