Jak można zaimportować moment.js za pomocą maszynopisu?

96

Próbuję się nauczyć maszynopisu. Chociaż uważam, że to nie jest istotne, używam VSCode do tego demo.

Mam to, package.jsonktóre zawiera te elementy:

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

Następnie mam taką klasę Typescript main.js:

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

Mój gulpfile.jswygląd wygląda tak:

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

Kiedy uruchamiam kompilację z łyka, otrzymuję komunikat: "../main.ts(1,25): Cannot file module 'moment'."

Jeśli używam, import moment = require('moment');jspm zadziała i wprowadzi moduł po uruchomieniu aplikacji, ale nadal otrzymuję błąd kompilacji. Próbowałem też:

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

Jednak zamiast poprawić sytuację, pogorszył się. Teraz pojawia się powyższy błąd podczas kompilacji, a także następujący:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Jeśli przejdę do pliku dostarczonego przez wpisywanie i dodam na dole pliku:

declare module "moment" { export = moment; }

Mogę usunąć drugi błąd, ale nadal potrzebuję instrukcji wymagania, aby mieć chwilę do pracy w moim main.ts pliku i nadal otrzymuję pierwszy błąd kompilacji.

Czy muszę .d.tsna chwilę utworzyć własny plik, czy brakuje mi tylko jakiegoś elementu konfiguracyjnego?

rozwój równoległy
źródło
1
Dodanie tej aktualizacji dla każdego, kto import moment, { Moment } from 'moment';const x = moment();const x: Moment = moment();
napotka
Żadne z tych rozwiązań nie zadziałało, przeniosłem się tutaj - github.com/date-fns/date-fns
chrismarx

Odpowiedzi:

124

Aktualizacja

Najwyraźniej moment dostarcza teraz własne definicje typów (zgodnie z sivabudh co najmniej od 2.14.1 wzwyż), więc nie potrzebujesz ich typingslub @typeswcale.

import * as moment from 'moment' powinien załadować definicje typu dostarczone z pakietem npm.

To powiedziawszy jednak, jak wspomniano w moment / pull / 3319 # issuecomment-263752265 w momencie, gdy wydaje się, że zespół ma problemy z utrzymaniem tych definicji (nadal szuka kogoś, kto je utrzymuje) .


Musisz zainstalować momenttypy bez --ambientflagi.

Następnie dołącz go za pomocą import * as moment from 'moment'

Pomocnicy
źródło
To się udało. Czy możesz wyjaśnić różnicę między używaniem --ambientflagi a nie? Mam numeraljs do pracy przy użyciu flagi otoczenia. Również ich strona główna npmjs.com/package/typings podaje przykład z użyciem flagi otoczenia. Nie wiem, kiedy chciałbym / musiałbym używać jednego nad drugim. Dzięki!
rozwój równoległy
1
Szczerze mówiąc, nie mogę. Zwykle używasz --ambientflagi dla wszystkich definicji Typescript z typings/, DefinitelyTypedale momentdefinicja ma dziwną strukturę i pliki nie są ładowane poprawnie. Jeśli spojrzysz na plik definicji moment.d.ts , zawiera on tylko odniesienie do wersji węzła, które nie jest rozwiązane podczas pobierania (może warto otworzyć problem).
Pomocnicy
Najwyraźniej jest już jeden związany z tym problemem: github.com/DefinitelyTyped/DefinitelyTyped/issues/8388
peinearydevelopment
1
Mam go do pracy przy użyciu importu * jako momentu z „chwili / chwili” b / c został zainstalowany jako podfolder w folderze node-modules.
user441058
1
Jestem na webpacku, a moment w wersji 2.17.1, ale nadal nie mogę go uruchomić. Próbowałem: import * jako moment z „chwili”; i importuj * jako moment od 'moment / moment'; i nie działa!
Mohy Eldeen
59

Musisz zaimportować moment () funkcję i Moment klasę oddzielnie w TS.

Znalazłem notatkę w dokumentach maszynopisu tutaj .

/ * ~ Zauważ, że moduły ES6 nie mogą bezpośrednio eksportować funkcji wywoływalnych
* ~ Ten plik powinien być importowany przy użyciu stylu CommonJS:
* ~ import x = require ('someLibrary');

Zatem kod importujący moment js do maszynopisu wygląda tak:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Koby
źródło
1
Dobra odpowiedź, ponieważ pokazuje różnicę między typem a funkcją. Dzięki!
Jelle den Burger
nie można znaleźć nazwy „wymagaj”
kontener zakodowany
4
Teraz można tego używać jako, import * as moment from 'moment';a następnie używać moment.Momentdo pisania.
meteor
U mnie zadziałało: import moment = require ('moment');
Telmo Pimentel Mota
Właściwie możesz również użyć moment.Momentinterfejsu bezpośrednio z przestrzeni nazwmoment
HalfWebDev
20

Nie jestem pewien, kiedy to się zmieniło, ale w najnowszej wersji maszynopisu wystarczy użyć import moment from 'moment'; i wszystko inne powinno działać normalnie.

AKTUALIZACJA:

Wygląda na to, że ostatnio naprawiono ich import. Przynajmniej 2.24.0będziesz chciał użyćimport * as moment from 'moment';

NSjonas
źródło
5
import * as moment from 'moment'nie działa z maszynopisem, ale import moment from 'moment'działa.
Stuart McIntyre
To działa, ale otrzymuję czas GMT 0, ale potrzebuję czasu lokalnego, który nie działa.Próbuję również z momentem (). Utc (). Format (), ale przywraca ten sam wynik.
kbhaskar
@kbhaskar od najnowszej wersji w momencie, gdy naprawili import. Zobacz zaktualizowaną odpowiedź
NSjonas
1
Myślę, że to prawie wszystko. Jedynym dodatkowym krokiem, jaki musiałem zrobić, było dodanie esModuleInteropzestawu truew mojej konfiguracji, który otrzymałem z tej odpowiedzi . Dzięki.
Mark Birbeck
14

za pomocą maszynopisów

Moment.js obsługuje teraz język TypeScript w wersji 2.14.1.

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


Bezpośrednio

Może nie jest to najlepsza odpowiedź, ale to metoda brutalnej siły i działa na mnie.

  1. Wystarczy pobrać aktualną wersję moment.js plik i umieść go w swoim projekcie.
  2. Na przykład mój projekt wygląda tak:

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

  1. A oto przykładowy kod źródłowy:

`` ''

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. Po prostu nodebiegnij main.js.
sivabudh
źródło
Tak, potwierdzam, że to właściwa odpowiedź. Działał jak urok.
Capy,
Kiedy próbuję to zrobić za pomocą npm i @ types / moment, pojawia się błąd: Błąd TypeScript: src \ app.ts (1,1): błąd TS7038: Nie można wywołać ani skonstruować importu w stylu przestrzeni nazw, co spowoduje awaria w czasie wykonywania. on tsc -v 2.7.2
GONeale
2

Właśnie zauważyłem, że odpowiedź, za którą głosowałem i skomentowałem, jest niejednoznaczna. Oto dokładnie to, co zadziałało dla mnie. Obecnie korzystam z Moment 2.26.0i TS 3.8.3:

W kodzie:

import moment from 'moment';

W konfiguracji TS:

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

Buduję zarówno dla CommonJS, jak i EMS, więc ta konfiguracja jest importowana do innych plików konfiguracyjnych.

Wgląd pochodzi z tej odpowiedzi, która dotyczy korzystania z Express. Pomyślałem, że warto to tutaj dodać, aby pomóc każdemu, kto szuka w związku z Moment.js, zamiast czegoś bardziej ogólnego.

Mark Birbeck
źródło
wtedy możesz używać moment()jak zwykle zamiastmoment.default()
xinthose
0

1. zainstalować moment

npm install moment --save

2. Przetestuj ten kod w swoim pliku maszynopisu

import moment = require('moment');

console.log(moment().format('LLLL'));
wytrzymała lutula
źródło
1
To nie jest właściwy sposób importowania modułu w maszynie. Rozważ aktualizację swojej odpowiedzi. Zapoznaj się z tym w celu potwierdzenia: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

Nadal zepsuty? Spróbuj odinstalować @types/moment.

Więc usunąłem @types/momentpakiet z package.jsonpliku i działał przy użyciu:

import * as moment from 'moment'

Nowsze wersje momentnie wymagają @types/momentpakietu, ponieważ typy są już uwzględnione.

Ben Winding
źródło