Moment: [TypeScript] «Ошибка TS2304: не удается найти имя 'moment'» при использовании с «module»: «none»

Созданный на 14 февр. 2017  ·  51Комментарии  ·  Источник: moment/moment

Похоже, что Typescript не может разрешить глобальную функцию moment() при использовании в немодульном контексте.

версия tsc: 2.1.6
момент версии: 2.17.1

Воспроизведение (при условии, что tsc находится на вашем $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'.

Однако использование типа модуля работает должным образом:

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

К сожалению, в моем проекте не используется сборщик или модульная система, поэтому я пока застрял с "module": "none" .

Моя единственная альтернатива - использовать что-то вроде typings install --save --global dt~moment ?

TypeScript Up-For-Grabs

Самый полезный комментарий

+1, пожалуйста, исправьте это

Все 51 Комментарий

У меня такая же проблема. Неважно, какой тип модуля вы укажете в tsconfig.json. Я получаю ту же ошибку, что и @rossipedia

Я сообщил о той же проблеме (https://github.com/moment/moment/issues/3663), но, к сожалению, она была просто закрыта без какой-либо реакции.

В итоге я скопировал moment.d.ts в свой каталог /scripts/app и реализовал исправление, указанное в https://github.com/moment/moment/issues/3663#issuecomment -273199291

Надеюсь, что в конце концов в moment.d.ts появится более постоянное исправление.

Я решил это, указав "moduleResolution": "node" в моем tsconfig. Не уверен, что этот вариант подходит вам, ребята, но, похоже, он помогает.

"moduleResolution": "node" , к сожалению, не помог мне

@rossipedia Мне тоже.

Не поможет ли добавить export as namespace moment; в файл moment.d.ts ?

См .: https://github.com/moment/moment/issues/3808

@czb, который, к сожалению, не

Я решил это с помощью пары хаков, о которых другие упоминали, около тонны проблем во многих проектах, в которых есть эта проблема. Просто заверните его в свой собственный файл определения. Это использует Typescript 2.2. Таким образом, я не возьмусь за зависимость, исходящую от npmjs.org, и мне не нужно проверять все это в системе управления версиями.

tsconfig.json

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

moment.custom.d.ts

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

Мне любопытно, почему это не работает, когда этот код добавляется непосредственно в moment.d.ts ? Я не могу не думать, что мы сталкиваемся с какой-то неясной ошибкой разрешения TypeScript, и, к сожалению, tsc не имеет подробного режима (о котором я знаю), который помог бы точно определить, где что-то идет не так.

Я думаю , что если вы определяете "module": "none" машинописи не ищет d.ts файлов под node_modules/moment папки. По моему опыту, он просматривает только папку node_modules/@types . Так что в основном есть эти варианты.

  1. Скопируйте moment.d.ts под node_modules/@types/moment
  2. Включите /// <reference path="./node_modules/moment/moment.d.ts" /> в свой .ts файл
  3. Звоните tsc --typeRoots node_modules test.ts
  4. Поместите ./node_modules/moment/moment.d.ts в files раздел tsconfig.json

Вам также необходимо добавить export as namespace moment; в файл moment.d.ts .

команде Moment понравятся любые PR, которые исправят это, но оставайтесь совместимыми с TS 1.x.

Мне еще предстоит найти решение, которое вообще работает, но когда я найду, я обязательно добавлю PR

Согласно # 3663 временное исправление, чтобы заставить его работать без какого-либо сборщика ...

  • Скопируйте moment.d.ts из node_modules/moment/ в node_modules/@types/moment

  • Измените export = moment; в moment.d.ts на

declare module "moment" {
    export = moment;
}
  • Переименуйте moment.d.ts в index.d.ts

Просто используйте момент и свой редактор (в моем случае vscode), и tsc не должен жаловаться

+1, пожалуйста, исправьте это

@mtgibbs Куда вы кладете файл moment.custom.d.ts? Требуется ли какая-либо другая конфигурация для вашего приложения, чтобы найти этот файл custom.d.ts?

@elSteeze

Да, я добавляю их в свои tsconfig.json . Вот очищенный пример:

{
  "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 Привет, спасибо, чувак! Оцените быстрый ответ. Я попробую.

@mtgibbs Извините за еще один вопрос, подобный

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

Я провел небольшое личное исследование и попытался реализовать решение, переписав moment.custom.d.ts, но, к сожалению, это не устранило мою проблему.

Извините, я не пытаюсь быть одним из тех надоедливых разработчиков, которые заставляют всех остальных отлаживать свой код, я недавний выпускник и новичок в работе со сторонними библиотеками в среде Angular 2.

Вот мой обновленный 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;

Без проблем. Если вы используете Angular 2, у вас должно быть 2.0+ TS. Я не работаю в Angular, поэтому не уверен. Не забудьте вставить все, что вы можете, из своего tsconfig.json, и я посмотрю, когда вернусь к настоящему компьютеру.

Конечно!

Это весь мой файл tsconfig.es5.json в каталоге src моего модуля angular 2, который я создаю.
Кстати я ценю помощь

{
  "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"
  ]
}

В какой версии TS вы компилируете? Вы должны просто иметь возможность импортировать момент вверху без моего взлома.

@mtgibbs Я использую v2.2, и вот что я подумал. К сожалению, это не работает. Я почти нахожусь на том этапе, когда пишу свою собственную версию функциональности, которую мы берем от momentjs, потому что я не могу заставить это работать.

@elSteeze

Хорошо, возвращаюсь сюда. Я заметил, что вы сказали, что создали собственный module.custom.d.ts , но затем вы ссылаетесь на мой moment.custom.d.ts в своем tsconfig.json . Убедитесь, что вы сделали moment.custom.d.ts и добавили его в свой компилятор, и ничего лишнего, что вы декларировали. Затем убедитесь, что вы ссылаетесь на него в верхней части файла, в котором хотите его использовать.

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

Это должно позволить вам ссылаться на нее как на глобальную переменную, как в моем первоначальном обходном пути.

Отличное спасибо,
Я изменил свою файловую структуру, чтобы поддерживать ваши пути. Итак, это правильные пути.
Ура, дружище!

Это работает для меня:

  • закомментировать // export = moment в официальном файле moment.d.ts
  • добавить node_modules/moment/moment.d.ts в tsconfig.json

Или скопируйте измененный moment.d.ts в любое место по вашему выбору и добавьте путь к нему в свой tsconfig.json

Я думаю, что основная проблема заключается в том, что при явном использовании "module":"none" в tsconfig.json у вас не может быть импорта или экспорта верхнего уровня в каких-либо библиотеках (потому что тогда вы используете модули).

вы должны сначала импортировать компонент как
импорт * как момент с «момента»;

это сработало для меня

вы должны сначала импортировать компонент как
импорт * как момент с «момента»;
это сработало для меня

Если вы сделаете это в файле, то разрешение пространства имен для этих файлов будет отключено.

Пожалуйста, ребята +1, чтобы исправить это

Почему бы вам не исправить эту проблему? Это очень важно.

Добавление "module": "commonjs" в tsconfig.json исправило это для меня

Но мне нужно использовать "module": "none" . Commonjs - это не решение.

Если я правильно понимаю, это будет решено с помощью функции типы import ing, не затрагивая контекст модуля / окружающей среды.

Я использую TS 3.0.1, теперь это решено? По крайней мере, из коробки не работает.

РЕДАКТИРОВАТЬ , с TS 3.0.1 я мог бы сделать только это:

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

Ура!

С tsconfig

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

TS 3.0.1, похоже, решает эту проблему (и он был открыт уже более полутора лет без поддержки)

Привет, россия,
У меня такая же проблема в проекте angular-6. Согласно вашим комментариям, это разрешено в TS 3.0.1, но angular6 CLI не поддерживает TypeScript версии 3.0.1.

Не могли бы вы помочь решить эту проблему?

Встречался ли еще кто-нибудь с пакетом @types/moment npm, который является просто заглушкой и предлагает вам использовать файл, предоставленный обычным пакетом moment?

... Почему момент должен делать это иначе, чем любой другой пакет? Это причина, по которой существует эта проблема, и разработчики потратили тысячи часов на ее решение.

Конечно, решение @Ciantic работает в TS 3.0.1, но мне не нужно использовать что-то вроде declare var moment: typeof import("moment"); для других пакетов, которые я использую.

Не похоже, что Typescript 3.0.1 исправит эту проблему, похоже, что это просто дает нам обходной путь.

похоже, это просто дает нам обходной путь.

Ага, именно так. Это неприемлемое «исправление».

Прошел всего день, и я только что понял, что обходной путь TS 3.0.1 импортирует только функцию moment , а не пространство / типы имен. Итак, если вы хотите передать объект момента в функцию, произойдет следующее:

image

Пожалуйста, откройте эту проблему повторно или лучше: исправьте файл .dts.

Не решение исходной проблемы, но для людей, которые будут искать это позже: указание следующего в tsconfig.json исправило это (машинописный текст 3.3.3 и момент 2.24.0)

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

В последнее время я больше не использую момент, но я рад снова открыть проблему, если она все еще актуальна.

ОШИБКА в src / app / services / get-list.service.ts (22,54): ошибка TS2304: не удается найти имя '_'.

какое решение для этого ??

@nagipogu Для этого нет решения, это проблема для moment.js , пожалуйста, откройте ее в репозитории underscore.js на Github .

У меня проблема с последней версией момента с последней версией TS. Есть ли у кого-нибудь успешное обходное решение?

Все еще не работает, решение для меня было yarn add -W [email protected] .

Когда я установил последнюю версию момента и заглянул в node_modules / moment / package.json, я увидел это: https://github.com/moment/moment/blob/develop/package.json#L29 - но существующего каталога не было node_modules/moment/ts3.1-typings , так что неудивительно, что TS не смог его найти. Я думаю, что может быть какая-то ошибка с установочным скриптом (или пакетом) или около того. Да, у нас есть "module": "esnext" в tsconfig.json.

Для меня это сломалось с 2.25.0:

Я использовал pnpm add [email protected] в качестве временного решения.

Для меня это сломалось с 2.25.0:

Я использовал pnpm add [email protected] в качестве временного решения.

хорошо работать, спасибо

Для меня это сломалось с 2.25.0:

Я использовал pnpm add [email protected] в качестве временного решения.

Здесь же он добавлен в: "dependencies" {"moment": "^ 2.24.0",
} ... вроде работает спасибо.

У меня тоже сработало понижение до 2.24.0. Похоже на регресс в 2.25.0.

2.25.3 устраняет ваши проблемы?

Существует так много разных ситуаций, в которых используется Moment.js, не говоря уже о TS 1.x, TS 2.x, TS 3.x ...
Я не решаюсь вносить изменения, которые нарушат работу какой-либо группы этих пользователей.

Если вы считаете, что документацию можно улучшить, отправьте сообщение на https://github.com/moment/momentjs.com/.

2.25.3 устраняет ваши проблемы?

да.

Откатился на 2.24.0, когда 2.25.1 у меня не удалось в Angular 9. С 2.25.3 он снова вернулся в нужное русло.

Ок, отлично. Я закрою пока.

Пожалуйста, повторно откройте (или откройте новый вопрос), если у вас все еще есть проблемы.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги