Bagaimana moment.js diimpor dengan skrip ketik?

96

Saya mencoba mempelajari Ketikan. Meskipun menurut saya ini tidak relevan, saya menggunakan VSCode untuk demo ini.

Saya memiliki package.jsonyang memiliki potongan-potongan ini di dalamnya:

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

Lalu saya memiliki kelas Ketikan main.jsseperti ini:

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

Saya gulpfile.jsterlihat seperti ini:

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

Ketika saya menjalankan gulp build, saya mendapatkan pesan: "../main.ts(1,25): Cannot file module 'moment'."

Jika saya menggunakan import moment = require('moment');maka jspm akan berfungsi dan membawa modul saat saya menjalankan aplikasi, tetapi saya masih menerima kesalahan pembuatan. Saya juga mencoba:

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

Alih-alih membuat masalah menjadi lebih baik, malah menjadi lebih buruk. Sekarang saya mendapatkan kesalahan di atas pada build serta yang berikut:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Jika saya pergi ke file yang disediakan oleh pengetikan dan menambahkan di bagian bawah file:

declare module "moment" { export = moment; }

Saya bisa mendapatkan kesalahan kedua untuk pergi, tetapi saya masih membutuhkan pernyataan yang diperlukan untuk mendapatkan waktu untuk bekerja di main.tsfile saya dan saya masih mendapatkan kesalahan pembuatan pertama.

Apakah saya perlu membuat .d.tsfile saya sendiri untuk sementara waktu atau hanya ada beberapa bagian penyiapan yang saya lewatkan?

peinearydevelopment
sumber
1
Menambahkan pembaruan ini untuk siapa saja yang mengalami ini sekarang: import moment, { Moment } from 'moment';memungkinkan Anda untuk melakukan const x = moment();danconst x: Moment = moment();
ryuu9187
Tak satu pun dari solusi ini bekerja, saya pindah ke sini - github.com/date-fns/date-fns
chrismarx

Jawaban:

124

Memperbarui

Rupanya moment sekarang memberikan definisi tipenya sendiri (menurut sivabudh minimal dari 2.14.1 ke atas), jadi anda tidak membutuhkan typingsatau tidak membutuhkan @typessama sekali.

import * as moment from 'moment' harus memuat definisi tipe yang disediakan dengan paket npm.

Namun demikian, seperti yang dikatakan pada moment / pull / 3319 # Issuecomment-263752265 , tim moment tampaknya memiliki beberapa masalah dalam mempertahankan definisi tersebut (mereka masih mencari seseorang yang memeliharanya) .


Anda perlu menginstal momentpengetikan tanpa --ambientbendera.

Kemudian sertakan menggunakan import * as moment from 'moment'

Ajudan
sumber
Itu berhasil. Bisakah Anda menjelaskan perbedaan antara menggunakan --ambientbendera dan tidak? Saya mendapat numeraljs untuk bekerja menggunakan bendera ambient. Juga, halaman utama mereka npmjs.com/package/typings memberikan contoh penggunaan ambient flag. Saya tidak tahu kapan saya ingin / perlu menggunakan salah satunya. Terima kasih!
peinearydevelopment
1
Sejujurnya, saya tidak bisa. Biasanya Anda menggunakan --ambientflag untuk semua definisi Typecript dari typings/ DefinitelyTypedtetapi momentdefinisi tersebut memiliki struktur yang aneh dan file tidak diunduh dengan benar. Jika Anda melihat file definisi moment.d.ts itu hanya berisi referensi ke versi node, yang tidak terselesaikan saat diunduh (mungkin layak membuka masalah).
Ajudan
Rupanya sudah ada satu hal yang berkaitan dengan masalah ini: github.com/DefinitelyTyped/DefinitelyTyped/issues/8388
peinearydevelopment
1
Saya membuatnya berfungsi menggunakan import * sebagai momen dari 'momen / momen' b / c itu diinstal sebagai subfolder di folder node-modules.
pengguna441058
1
Saya menggunakan webpack, dan saat ini versi 2.17.1 tetapi masih tidak bisa berfungsi. Saya mencoba: impor * sebagai momen dari 'momen'; dan impor * sebagai momen dari 'momen / momen'; dan tidak bekerja!
Mohy Eldeen
59

Anda perlu mengimpor moment () fungsi dan Momen kelas secara terpisah di TS.

Saya menemukan catatan di dokumen ketikan di sini .

/ * ~ Perhatikan bahwa modul ES6 tidak bisa langsung mengekspor fungsi yang dapat dipanggil
* ~ File ini harus diimpor menggunakan CommonJS-style:
* ~ import x = require ('someLibrary');

Jadi kode untuk mengimpor momen js ke dalam skrip ketikan sebenarnya terlihat seperti ini:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Koby
sumber
1
Jawaban yang bagus karena menunjukkan perbedaan antara tipe dan fungsinya. Terima kasih!
Jelle den Burger
tidak dapat menemukan nama 'membutuhkan'
Wadah
4
Sekarang ini dapat digunakan sebagai import * as moment from 'moment';dan kemudian digunakan moment.Momentuntuk pengetikan.
meteor
Apa yang berhasil bagi saya adalah: import moment = require ('moment');
Telmo Pimentel Mota
Sebenarnya Anda juga dapat menggunakan moment.Momentantarmuka langsung dari namespacemoment
HalfWebDev
20

Tidak yakin kapan ini berubah, tetapi dengan versi skrip terbaru, Anda hanya perlu menggunakan import moment from 'moment';dan yang lainnya akan bekerja seperti biasa.

MEMPERBARUI:

Sepertinya beberapa saat terakhir memperbaiki impor mereka. Setidaknya 2.24.0Anda ingin menggunakanimport * as moment from 'moment';

NSjonas
sumber
5
import * as moment from 'moment'tidak akan bekerja dengan skrip tetapi berfungsi import moment from 'moment'.
Stuart McIntyre
Ini berfungsi tetapi saya mendapatkan waktu GMT 0, tetapi saya perlu waktu lokal yang tidak berfungsi. Saya juga mencoba dengan moment (). Utc (). Format () tetapi mengembalikan hasil yang sama.
kbhaskar
@kbhaskar untuk versi terbaru saat mereka telah memperbaiki impornya. Lihat jawaban yang diperbarui
NSjonas
1
Saya pikir ini cukup banyak. Satu-satunya langkah tambahan yang harus saya lakukan adalah menambahkan esModuleInteropset ke truedalam konfigurasi saya, yang saya dapatkan dari jawaban ini . Terima kasih.
Mark Birbeck
14

melalui pengetikan

Moment.js sekarang mendukung TypeScript di v2.14.1.

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


Langsung

Mungkin bukan jawaban terbaik, tapi ini cara kekerasan, dan itu berhasil untuk saya.

  1. Cukup unduh moment.jsfile sebenarnya dan sertakan dalam proyek Anda.
  2. Misalnya, proyek saya terlihat seperti ini:

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

  1. Dan inilah contoh kode sumbernya:

``

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. Gunakan saja nodeuntuk lari main.js.
sivabudh.dll
sumber
Ya, saya mengonfirmasi bahwa ini adalah jawaban yang tepat. Bekerja seperti pesona.
Capy
Ketika saya mencoba melakukan ini menggunakan npm i @ types / moment, saya menerima kesalahan: Kesalahan TypeScript: src \ app.ts (1,1): kesalahan TS7038: Impor gaya namespace tidak dapat dipanggil atau dibuat, dan akan menyebabkan kegagalan saat runtime. di tsc -v 2.7.2
GONeale
2

Saya baru saja memperhatikan bahwa jawaban yang saya beri suara positif dan dikomentari tidak jelas. Jadi berikut ini persis apa yang berhasil untuk saya. Saya saat ini di Momen 2.26.0dan TS 3.8.3:

Dalam kode:

import moment from 'moment';

Dalam konfigurasi TS:

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

Aku membangun untuk kedua CommonJS dan EMS sehingga konfigurasi ini diimpor ke file konfigurasi lainnya.

Wawasan berasal dari jawaban ini yang berkaitan dengan penggunaan Express. Saya pikir itu layak ditambahkan di sini, untuk membantu siapa saja yang mencari terkait dengan Moment.js, daripada sesuatu yang lebih umum.

Mark Birbeck
sumber
maka Anda dapat menggunakan moment()seperti biasa, bukanmoment.default()
xinthose
0

1. pasang momen

npm install moment --save

2. uji kode ini dalam file skrip Anda

import moment = require('moment');

console.log(moment().format('LLLL'));
lutula yang kuat
sumber
1
Ini bukan cara yang tepat untuk mengimpor modul dalam skrip ketikan. Harap pertimbangkan untuk memperbarui jawaban Anda. Lihat ini untuk konfirmasi: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

Masih rusak? Coba copot pemasangan @types/moment.

Jadi, saya menghapus @types/momentpaket dari package.jsonfile dan bekerja menggunakan:

import * as moment from 'moment'

Versi yang lebih baru momenttidak memerlukan @types/momentpaket karena jenis sudah disertakan.

Ben Winding
sumber