Typescript scheint die globale moment()
Funktion nicht aufzulösen, wenn es in einem Nicht-Modul-Kontext verwendet wird.
tsc-Version: 2.1.6
Momentversion: 2.17.1
Repro (vorausgesetzt, tsc
befindet sich auf Ihrem $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'.
Die Verwendung eines Modultyps funktioniert jedoch wie erwartet:
$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js
Leider verwendet mein Projekt kein Bundler- oder Modulsystem, daher bleibe ich vorerst bei "module": "none"
.
Ist meine einzige Alternative, etwas wie typings install --save --global dt~moment
?
ich stehe vor dem gleichen Problem. Es spielt keine Rolle, welchen Modultyp Sie in tsconfig.json angeben. Ich bekomme den gleichen Fehler wie @rossipedia
Ich habe das gleiche Problem gemeldet (https://github.com/moment/moment/issues/3663), aber leider wurde es einfach ohne Reaktion geschlossen.
Am Ende habe ich moment.d.ts
in mein /scripts/app
Verzeichnis kopiert und den in https://github.com/moment/moment/issues/3663#issuecomment -273199291 angegebenen Fix implementiert
Hoffentlich wird irgendwann eine dauerhaftere Lösung seinen Weg in moment.d.ts
.
Ich habe dies gelöst, indem ich "moduleResolution": "node"
in meiner tsconfig angegeben habe. Ich bin mir nicht sicher, ob dies eine Option für Sie ist, aber es scheint den Zweck zu erfüllen.
"moduleResolution": "node"
hat es leider nicht für mich behoben
@rossipedia Ich auch nicht.
Wäre es nicht hilfreich, export as namespace moment;
in die Datei moment.d.ts
einzufügen?
@czb das hat das Problem bei mir leider auch nicht
Ich habe dies mit ein paar Hacks gelöst, die andere in vielen Projekten erwähnt haben, die dieses Problem haben. Wickeln Sie es einfach in eine eigene benutzerdefinierte Definitionsdatei ein. Dies verwendet Typescript 2.2. Auf diese Weise mache ich mich nicht mit der Abhängigkeit von npmjs.org herum und muss das Ganze nicht in die Quellcodeverwaltung einchecken.
tsconfig.json
"compilerOptions": {
"target": "ES5",
"moduleResolution": "node",
...
}
moment.custom.d.ts
import * as _moment from 'moment';
export as namespace moment;
export = _moment;
Ich bin neugierig, warum das nicht funktioniert, wenn dieser Code direkt zu moment.d.ts
hinzugefügt wird? Ich kann nicht anders, als zu denken, dass wir in einen obskuren TypeScript-Auflösungsfehler geraten, und leider hat tsc
keinen ausführlichen Modus (den ich kenne), der helfen würde, genau zu erkennen, wo etwas schief läuft.
Ich denke, wenn Sie "module": "none"
definieren, sucht Typescript nicht nach d.ts
Dateien im Ordner node_modules/moment
. Meine Erfahrung ist, dass es nur im Ordner node_modules/@types
sucht. Es gibt also grundsätzlich diese Möglichkeiten.
moment.d.ts
unter node_modules/@types/moment
/// <reference path="./node_modules/moment/moment.d.ts" />
in Ihre .ts
Datei eintsc --typeRoots node_modules test.ts
./node_modules/moment/moment.d.ts
in den Abschnitt files
von tsconfig.json
Außerdem müssen Sie export as namespace moment;
in die Datei moment.d.ts
einfügen.
Das Moment-Team würde sich über alle PRs freuen, die dies beheben würden, aber TS 1.x-kompatibel bleiben.
Ich muss noch eine Lösung finden, die überhaupt funktioniert, aber wenn ich es tue, werde ich auf jeden Fall einen PR hinzufügen
Laut #3663 der temporäre Fix, um es ohne Bundler zum Laufen zu bringen...
Kopieren Sie moment.d.ts
von node_modules/moment/
nach node_modules/@types/moment
Ändere export = moment;
in moment.d.ts
in
declare module "moment" {
export = moment;
}
moment.d.ts
in index.d.ts
Verwenden Sie einfach moment und Ihr Editor (in meinem Fall vscode) und tsc sollten sich nicht beschweren
+1 bitte korrigiere das
@mtgibbs Wo
@elSteeze
Ja, ich füge sie zu meinem tsconfig.json
. Hier ist ein geschrubbtes Beispiel:
{
"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 Hey danke Mann! Schätzen Sie die schnelle Antwort. Ich werde das versuchen.
@mtgibbs Entschuldigung für eine weitere Noob-ähnliche Frage, nach der Implementierung Ihrer Lösung bekam ich Editor-Fehler beim Moment-Schlüsselwort in meinem ts-Code ...
'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead
Ich habe persönlich recherchiert und versucht, eine Lösung zu implementieren, indem ich moment.custom.d.ts neu geschrieben habe, aber leider hat das mein Problem nicht behoben.
Entschuldigung, ich versuche nicht, einer dieser lästigen Entwickler zu sein, die alle anderen dazu bringen, ihren Code zu debuggen. Ich bin ein Absolvent und neu in der Arbeit mit Bibliotheken von Drittanbietern in einer Angular 2-Umgebung
Hier ist mein aktualisiertes module.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;
Kein Problem. Wenn Sie Angular 2 verwenden, sollten Sie 2.0+ TS verwenden. Ich arbeite nicht in Angular, daher bin ich mir nicht sicher. Denken Sie daran, alles von Ihrer tsconfig.json einzufügen, und ich schaue nach, wenn ich wieder auf einem echten Computer bin.
Sicher!
Dies ist meine gesamte Datei tsconfig.es5.json im src-Verzeichnis meines Winkel-2-Moduls, das ich baue.
Ich freue mich übrigens über die Hilfe
{
"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"
]
}
In welcher TS-Version kompilieren Sie? Sie sollten nur in der Lage sein, den Moment oben ohne meinen Hack zu importieren.
@mtgibbs Ich verwende v2.2, und das dachte ich mir. Leider funktioniert es nicht. Ich bin fast an dem Punkt angelangt, an dem ich meine eigene Version der Funktionalität schreibe, die wir von momentjs übernehmen, weil ich das anscheinend nicht zum Laufen bekomme.
@elSteeze
Okay, zurück hierher. Mir ist aufgefallen, dass Sie gesagt haben, dass Sie ein benutzerdefiniertes module.custom.d.ts
, aber dann beziehen Sie sich auf mein moment.custom.d.ts
in Ihrem tsconfig.json
. Stellen Sie sicher, dass Sie moment.custom.d.ts
und Ihrem Compiler hinzugefügt haben, nichts von diesem zusätzlichen Zeug, das Sie als Dinge deklarieren mussten. Stellen Sie dann sicher, dass Sie es oben in der Datei referenzieren, in der Sie es verwenden möchten.
/// <reference path="path/to/your/moment.custom.d.ts" />
Dies sollte es Ihnen ermöglichen, wie in meiner ursprünglichen Problemumgehung als globale Variable darauf zu verweisen.
Super danke
Ich habe meine Dateistruktur geändert, um Ihre Pfade zu unterstützen. Das sind also die richtigen Pfade.
Prost Kumpel!
Das funktioniert bei mir:
// export = moment
in der offiziellen Datei moment.d.ts ausnode_modules/moment/moment.d.ts
zu tsconfig.json
hinzufügenKopieren Sie alternativ das geänderte moment.d.ts
an einen Ort Ihrer Wahl und fügen Sie den Pfad dazu in Ihrem tsconfig.json
Ich denke, das Hauptproblem besteht darin, dass Sie bei expliziter Verwendung von "module":"none"
in tsconfig.json keinen Import oder Export auf oberster Ebene in Bibliotheken haben können (weil Sie dann Module verwenden).
Sie müssen zuerst in die Komponente importieren als
import * als Moment von "moment";
bei mir hat es gut geklappt
Sie müssen zuerst in die Komponente importieren als
import * als Moment von "moment";
bei mir hat es gut geklappt
Wenn Sie dies in einer Datei tun, wird die Namensraumauflösung für diese Dateien deaktiviert.
Bitte Leute +1 um das zu beheben
Warum beheben Sie dieses Problem nicht? Es ist sehr wichtig.
Das Hinzufügen von "module": "commonjs"
zu den tsconfig.json
es für mich behoben
Aber ich muss "module": "none"
. Commonjs ist keine Lösung.
Wenn ich es richtig verstehe, wird dies mit der Importtypenfunktion von TypeScript 2.9 gelöst, die es ermöglicht, import
Typdefinitionen zu erstellen, ohne den Modul-/Umgebungskontext zu beeinflussen.
Ich verwende TS 3.0.1, ist das jetzt gelöst? Es funktioniert zumindest nicht out of the box.
BEARBEITEN , Mit TS 3.0.1 könnte ich genau das tun:
declare var moment: typeof import("moment");
Hurra!
Mit tsconfig
{
"compilerOptions": {
"module": "none"
"moduleResolution": "node",
// ...
}
}
TS 3.0.1 scheint dieses Problem zu beheben (und es ist seit über anderthalb Jahren ohne Traktion geöffnet)
Hallo Rossipedia,
Ich stehe vor dem gleichen Problem im Angular-6-Projekt. Laut Ihren Kommentaren ist es in TS 3.0.1 behoben, aber die angle6 CLI unterstützt die TypeScript-Version 3.0.1 nicht.
Können Sie bitte helfen, dieses Problem zu lösen?
Ist jemand anderem auch das npm-Paket @types/moment
begegnet, das nur ein Stub ist und Sie auffordert, die Datei zu verwenden, die vom normalen Moment-Paket bereitgestellt wird?
... Warum muss moment es anders machen als jedes andere Paket? Dies ist der Grund, warum dieses Problem existiert, und Tausende von Stunden wurden von Entwicklern damit verbracht, damit zu kämpfen.
Sicher, die Lösung von @Ciantic funktioniert in TS 3.0.1, aber ich muss für keines der anderen Pakete, die ich verwende, etwas wie declare var moment: typeof import("moment");
verwenden.
Es sieht nicht so aus, als hätte Typescript 3.0.1 dieses Problem behoben, es sieht so aus, als ob es uns nur einen Workaround bietet.
es sieht so aus, als ob es uns nur einen Workaround gibt.
Ja, genau das ist es. Dies ist keine akzeptable "Lösung".
Es ist erst ein Tag her und ich habe gerade festgestellt, dass der Workaround von TS 3.0.1 nur die moment
Funktion importiert, nicht den Namespace/die Typen. Wenn Sie also ein Momentobjekt an eine Funktion übergeben möchten, passiert Folgendes:
Bitte öffnen Sie dieses Problem erneut, oder besser: Beheben Sie die .dts-Datei.
Keine Lösung für das ursprüngliche Problem, aber für Leute, die das später googeln: Die Angabe des folgenden in tsconfig.json hat es behoben (Typoskript 3.3.3 und Moment 2.24.0)
{
"compilerOptions": {
"module": "commonjs"
}
}
Momentan nutze ich moment nicht mehr viel, aber ich freue mich, das Problem erneut zu öffnen, wenn es noch gültig ist.
was ist die lösung dafür??
@nagipogu Keine Lösung dafür, dieses Problem ist für moment.js , bitte öffnen Sie Ihr Problem im Github-Repository von underscore.js .
Ich stoße auf dieses Problem mit der neuesten Version von Moment mit der neuesten Version von TS. Hat jemand einen erfolgreichen Workaround?
Funktioniert immer noch nicht, die Lösung für mich war yarn add -W [email protected]
.
Als ich die neueste Moment-Version installierte und in node_modules/moment/package.json nachsah, sah ich Folgendes: https://github.com/moment/moment/blob/develop/package.json#L29 - aber es gab kein vorhandenes Verzeichnis node_modules/moment/ts3.1-typings
, daher überrascht es nicht, dass TS es nicht finden konnte. Ich denke, es könnte ein Fehler mit einem Installationsskript (oder einem Paket) oder so sein. Ja, wir haben "module": "esnext"
in tsconfig.json.
Bei mir brach es mit 2.25.0:
Ich habe pnpm add [email protected] als temporäre
Bei mir brach es mit 2.25.0:
Ich habe pnpm add [email protected] als temporäre
funktioniert gut, danke
Bei mir brach es mit 2.25.0:
Ich habe pnpm add [email protected] als temporäre
Dasselbe hier fügte es hinzu: "dependencies" {"moment": "^2.24.0",
}...scheint zu funktionieren danke.
Ein Downgrade auf 2.24.0 hat bei mir auch funktioniert. Sieht aus wie eine Regression in 2.25.0.
Behebt 2.25.3 Ihre Probleme?
Es gibt so viele verschiedene Situationen, in denen Moment.js verwendet wird, geschweige denn TS 1.x, TS 2.x, TS 3.x...
Ich zögere, Änderungen vorzunehmen, die jede Gruppe dieser Benutzer beeinträchtigen.
Wenn Sie der Meinung sind, dass die Dokumentation verbessert werden kann, posten Sie bitte unter https://github.com/moment/momentjs.com/
Behebt 2.25.3 Ihre Probleme?
Ja.
Rollback auf 2.24.0, als 2.25.1 für mich in Angular 9 fehlgeschlagen ist. Mit 2.25.3 ist es wieder auf Kurs.
Okay, großartig. Ich schließe vorerst.
Bitte öffnen Sie erneut (oder eröffnen Sie eine neue Ausgabe), wenn Sie weiterhin Bedenken haben.
Hilfreichster Kommentar
+1 bitte korrigiere das