Moment: [TypeScript] "kesalahan TS2304: Tidak dapat menemukan nama 'momen'" saat digunakan dengan "modul": "tidak ada"

Dibuat pada 14 Feb 2017  ·  51Komentar  ·  Sumber: moment/moment

TypeScript tampaknya tidak dapat menyelesaikan fungsi global moment() saat digunakan dalam konteks non-modul.

versi tsc: 2.1.6
versi momen: 2.17.1

Repro (dengan asumsi tsc ada di $PATH ):

$ mkdir repro && cd repro
$ npm i moment
$ echo 'const now = moment();' > test.ts
$ tsc --module none test.ts
test.ts(1,13): error TS2304: Cannot find name 'moment'.

Namun, menggunakan tipe modul berfungsi seperti yang diharapkan:

$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js

Sayangnya, proyek saya tidak menggunakan bundler atau sistem modul, jadi saya terjebak dengan "module": "none" untuk saat ini.

Apakah satu-satunya alternatif saya untuk menggunakan sesuatu seperti typings install --save --global dt~moment ?

TypeScript Up-For-Grabs

Komentar yang paling membantu

+1 tolong perbaiki ini

Semua 51 komentar

Saya menghadapi masalah yang sama. Tidak masalah jenis modul apa yang Anda tentukan di tsconfig.json. Saya mendapatkan kesalahan yang sama dengan @rossipedia

Saya melaporkan masalah yang sama (https://github.com/moment/moment/issues/3663), tetapi sayangnya itu ditutup begitu saja tanpa reaksi apa pun.

Saya akhirnya menyalin moment.d.ts ke direktori /scripts/app dan menerapkan perbaikan yang ditentukan di https://github.com/moment/moment/issues/3663#issuecomment -273199291

Semoga perbaikan yang lebih permanen akan berhasil mencapai moment.d.ts akhirnya.

Saya memecahkan ini dengan menentukan "moduleResolution": "node" di file tsconfig.php saya. Tidak yakin apakah ini pilihan untuk kalian, tetapi tampaknya berhasil.

"moduleResolution": "node" tidak memperbaikinya untuk saya, sayangnya

@rossipedia Saya juga.

Tidakkah membantu menambahkan export as namespace moment; ke dalam file moment.d.ts ?

Lihat: https://github.com/moment/moment/issues/3808

@czb yang juga tidak memperbaiki masalah untuk saya, sayangnya :(

Saya telah menyelesaikan ini menggunakan beberapa peretasan yang telah disebutkan orang lain tentang banyak masalah di banyak proyek yang mengalami masalah ini. Bungkus saja dalam file definisi khusus Anda sendiri. Ini menggunakan TypeScript 2.2. Dengan cara ini saya tidak terganggu dengan ketergantungan yang turun dari npmjs.org dan saya tidak perlu memeriksa semuanya ke dalam kontrol sumber.

tsconfig.json

"compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    ...
}

moment.custom.d.ts

import * as _moment from 'moment';
export as namespace moment;
export = _moment;

Saya ingin tahu mengapa itu tidak berhasil ketika kode itu ditambahkan langsung ke moment.d.ts ? Mau tak mau saya berpikir kita sedang menghadapi beberapa bug resolusi TypeScript yang tidak jelas, dan sayangnya tsc tidak memiliki mode verbose (yang saya tahu) yang akan membantu menunjukkan dengan tepat di mana ada yang salah.

Saya pikir jika Anda mendefinisikan "module": "none" TypeScript tidak mencari file d.ts bawah folder node_modules/moment . Pengalaman saya adalah hanya mencari di bawah folder node_modules/@types . Jadi pada dasarnya ada opsi ini.

  1. Salin moment.d.ts bawah node_modules/@types/moment
  2. Sertakan /// <reference path="./node_modules/moment/moment.d.ts" /> ke dalam file .ts
  3. Hubungi tsc --typeRoots node_modules test.ts
  4. Masukkan ./node_modules/moment/moment.d.ts ke bagian files dari tsconfig.json

Anda juga perlu menambahkan export as namespace moment; ke dalam file moment.d.ts .

tim Momen akan menyukai PR apa pun yang akan memperbaikinya, tetapi tetap kompatibel dengan TS 1.x.

Saya masih belum menemukan solusi yang berhasil sama sekali, tetapi ketika saya melakukannya, saya pasti akan menambahkan PR

Menurut #3663 perbaikan sementara untuk membuatnya berfungsi tanpa bundler apa pun ...

  • Salin moment.d.ts dari node_modules/moment/ ke node_modules/@types/moment

  • Ubah export = moment; di moment.d.ts menjadi

declare module "moment" {
    export = moment;
}
  • Ganti nama moment.d.ts menjadi index.d.ts

Cukup gunakan momen dan editor Anda (dalam kasus saya vscode ) dan tsc tidak boleh mengeluh

+1 tolong perbaiki ini

@mtgibbs Di mana Anda meletakkan file moment.custom.d.ts? Apakah ada konfigurasi lain yang perlu dilakukan agar aplikasi Anda dapat menemukan file custom.d.ts ini?

@elSteeze

Ya, saya menambahkannya ke tsconfig.json . Berikut ini contoh yang digosok:

{
  "compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./path/to/typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./path/to/typings/moment.custom.d.ts",
    "./path/to/src/**/*.ts"
  ]
}

@mtgibbs Hei, terima kasih

@mtgibbs Maaf untuk pertanyaan seperti noob lain, setelah menerapkan solusi Anda, saya mulai mendapatkan kesalahan editor pada kata kunci saat ini dalam kode ts saya ...

'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead

Saya melakukan riset pribadi dan mencoba menerapkan solusi dengan menulis ulang moment.custom.d.ts tetapi sayangnya, itu tidak memperbaiki masalah saya.

Maaf, tidak mencoba menjadi salah satu dari pengembang sial yang membuat orang lain men-debug kode mereka, saya lulusan baru dan saya baru bekerja dengan perpustakaan pihak ke-3 di lingkungan Angular 2

Ini modul saya yang diperbarui.custom.d.ts

declare var moment: any;
declare var module: NodeModule;
interface NodeModule {
    id: string;
}
import * as _moment from 'moment';
export as namespace moment;
export = _moment;

Tidak masalah. Jika Anda menggunakan Angular 2, Anda harus menggunakan 2.0+ TS. Saya tidak bekerja di Angular jadi saya tidak yakin. Silakan tempelkan apa yang Anda bisa dari tsconfig.json Anda dan saya akan memeriksanya setelah saya kembali ke komputer yang sebenarnya.

Tentu!

Ini adalah seluruh file tsconfig.es5.json saya di dalam direktori src dari modul angular 2 yang saya buat.
Saya menghargai bantuannya

{
  "compilerOptions": {
    "declaration": true,
    "module": "es2015",
    "target": "es5",
    "baseUrl": ".",
    "stripInternal": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "outDir": "../build",
    "rootDir": ".",
    "lib": [
      "es2015",
      "dom"
    ],
    "skipLibCheck": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./typings/moment.custom.d.ts",
    "./src/**/*.ts"
  ],
  "angularCompilerOptions": {
    "annotateForClosureCompiler": true,
    "strictMetadataEmit": true,
    "skipTemplateCodegen": true,
    "flatModuleOutFile": "new-version-library.js",
    "flatModuleId": "new-version-library"
  },
  "files": [
    "./index.ts"
  ]
}

Versi TS apa yang Anda kompilasi? Anda seharusnya dapat mengimpor momen di atas tanpa retas saya.

@mtgibbs Saya menggunakan v2.2, dan itulah yang saya pikirkan. Sayangnya, itu tidak berfungsi. Saya hampir pada titik di mana saya menulis versi saya sendiri dari fungsionalitas yang kami ambil dari momentjs, karena sepertinya saya tidak bisa menjalankannya.

@elSteeze

Oke, kembali ke sini. Saya perhatikan bahwa Anda mengatakan bahwa Anda telah membuat module.custom.d.ts , tetapi kemudian Anda merujuk ke moment.custom.d.ts di tsconfig.json . Pastikan Anda telah membuat moment.custom.d.ts dan menambahkannya ke kompiler Anda, tidak ada barang tambahan yang telah Anda nyatakan. Kemudian pastikan Anda mereferensikannya di bagian atas file tempat Anda ingin menggunakannya.

/// <reference path="path/to/your/moment.custom.d.ts" />

Ini akan memungkinkan Anda untuk mereferensikannya sebagai variabel global seperti dalam solusi asli saya.

Luar biasa terima kasih @mtgibbs ! Saya sangat menghargai bantuannya.
Saya mengubah struktur file saya untuk mendukung jalur Anda. Jadi itu adalah jalan yang benar.
Salut kawan!

Ini bekerja untuk saya:

  • komentar // export = moment di file moment.d.ts resmi
  • tambahkan node_modules/moment/moment.d.ts ke tsconfig.json

Sebagai alternatif, salin moment.d.ts dimodifikasi ke lokasi pilihan Anda dan tambahkan jalur ke sana di tsconfig.json

Saya pikir masalah utamanya adalah ketika secara eksplisit menggunakan "module":"none" di tsconfig.json Anda tidak dapat memiliki impor atau ekspor tingkat atas di perpustakaan mana pun (karena Anda kemudian menggunakan modul).

Anda harus mengimpor komponen terlebih dahulu sebagai
import * sebagai momen dari "momen";

itu bekerja dengan baik untuk saya

Anda harus mengimpor komponen terlebih dahulu sebagai
import * sebagai momen dari "momen";
itu bekerja dengan baik untuk saya

Jika Anda melakukannya dalam sebuah file, maka resolusi namespace dinonaktifkan untuk file tersebut.

Tolong teman-teman +1 untuk memperbaikinya

Mengapa Anda tidak memperbaiki masalah ini? Ini sangat penting.

Menambahkan "module": "commonjs" ke tsconfig.json memperbaikinya untuk saya

Tetapi saya harus menggunakan "module": "none" . Commonjs bukanlah solusi.

Jika saya memahaminya dengan benar, ini akan diselesaikan dengan fitur tipe impor TypeScript 2.9 , yang akan memungkinkan definisi tipe import tanpa memengaruhi modul/konteks ambien.

Saya menggunakan TS 3.0.1, apakah ini sekarang terpecahkan? Itu tidak bekerja di luar kotak setidaknya.

EDIT , Dengan TS 3.0.1 saya bisa melakukan ini:

declare var moment: typeof import("moment");

Hore!

Dengan tsconfig

{
    "compilerOptions": {
        "module": "none"
        "moduleResolution": "node", 
        // ...
    }
}

TS 3.0.1 tampaknya memperbaiki masalah ini (dan sudah terbuka selama lebih dari satu setengah tahun tanpa daya tarik)

Hai rossipedia,
Saya menghadapi masalah yang sama dalam proyek angular-6. Sesuai komentar Anda, ini diselesaikan di TS 3.0.1 tetapi angular6 CLI tidak mendukung TypeScript versi 3.0.1.

Bisakah Anda membantu menyelesaikan masalah ini?

Apakah ada orang lain yang juga menemukan paket @types/moment npm yang hanya berupa rintisan dan memberitahu Anda untuk menggunakan file yang disediakan oleh paket momen normal?

... Mengapa momen harus melakukannya secara berbeda dibandingkan dengan setiap paket lainnya? Inilah alasan mengapa masalah ini ada, dan ribuan jam dihabiskan oleh pengembang yang berjuang dengan ini.

Tentu, solusi @Ciantic bekerja di TS 3.0.1, tetapi saya tidak harus menggunakan sesuatu seperti declare var moment: typeof import("moment"); untuk paket lain yang saya gunakan.

Sepertinya TypeScript 3.0.1 tidak memperbaiki masalah itu, sepertinya itu hanya memberi kami solusi.

sepertinya itu hanya memberi kami solusi.

Yup, justru ini. Ini bukan "perbaikan" yang dapat diterima.

Baru sehari dan saya baru menyadari bahwa solusi TS 3.0.1 hanya mengimpor fungsi moment , bukan namespace/types. Jadi jika Anda ingin melewatkan objek momen ke dalam suatu fungsi, ini terjadi:

image

Silakan buka kembali masalah ini, atau lebih baik: perbaiki file .dts.

Bukan solusi untuk masalah awal, tetapi untuk orang-orang yang mencari di Google nanti: menentukan yang berikut di tsconfig.json memperbaikinya (TypeScript 3.3.3 dan momen 2.24.0)

{
  "compilerOptions": {
    "module": "commonjs"
  }
}

Saya tidak lagi menggunakan momen untuk banyak hari ini, tetapi saya senang untuk membuka kembali masalah jika masih valid.

KESALAHAN di src/app/services/get-list.service.ts (22,54): kesalahan TS2304: Tidak dapat menemukan nama '_'.

apa solusi untuk ini??

@nagipogu Tidak ada solusi untuk itu, masalah ini untuk moment.js , silakan buka masalah Anda di repositori Github underscore.js .

Saya mengalami masalah ini dengan versi terbaru saat dengan versi terbaru dari TS. Apakah ada yang punya solusi yang sukses?

Masih tidak berfungsi, solusi bagi saya adalah yarn add -W [email protected] .

Ketika saya menginstal versi momen terbaru dan melihat ke node_modules/moment/package.json, saya melihat ini: https://github.com/moment/moment/blob/develop/package.json#L29 - tetapi tidak ada direktori yang ada node_modules/moment/ts3.1-typings , jadi tidak heran TS tidak dapat menemukannya. Saya pikir mungkin ada beberapa bug dengan skrip instalasi (atau paket) atau lebih. Ya, kami memiliki "module": "esnext" di tsconfig.json.

Bagi saya itu rusak dengan 2.25.0:

Saya menggunakan pnpm add [email protected] sebagai solusi sementara.

Bagi saya itu rusak dengan 2.25.0:

Saya menggunakan pnpm add [email protected] sebagai solusi sementara.

berfungsi dengan baik, terima kasih

Bagi saya itu rusak dengan 2.25.0:

Saya menggunakan pnpm add [email protected] sebagai solusi sementara.

Sama di sini menambahkannya ke : "dependencies" {"moment": "^2.24.0",
}...tampaknya berhasil terima kasih.

Menurunkan versi ke 2.24.0 juga berhasil untuk saya. Sepertinya regresi di 2.25.0.

Apakah 2.25.3 memperbaiki masalah Anda?

Ada begitu banyak jenis situasi di mana Moment.js digunakan, apalagi TS 1.x, TS 2.x, TS 3.x...
Saya ragu untuk membuat perubahan yang merusak kelompok pengguna ini.

Jika menurut Anda dokumentasi dapat ditingkatkan, silakan posting di https://github.com/moment/momentjs.com/

Apakah 2.25.3 memperbaiki masalah Anda?

Ya.

Digulung kembali ke 2.24.0 ketika 2.25.1 gagal untuk saya di Angular 9. Dengan 2.25.3 itu kembali ke jalurnya lagi.

OK bagus. Saya akan tutup untuk saat ini.

Silakan buka kembali (atau buka edisi baru) jika Anda masih memiliki masalah.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

danieljsinclair picture danieljsinclair  ·  3Komentar

paulyoung picture paulyoung  ·  3Komentar

alvarotrigo picture alvarotrigo  ·  3Komentar

tanepiper picture tanepiper  ·  3Komentar

vbullinger picture vbullinger  ·  3Komentar