Как можно импортировать moment.js с помощью машинописного текста?

96

Я пытаюсь изучить Машинопись. Хотя я не думаю, что это актуально, я использую VSCode для этой демонстрации.

У меня package.jsonесть такие штуки:

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

Затем у меня есть такой класс Typescript main.js:

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

Мой gulpfile.jsвыглядит так:

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

Когда я запускаю gulp build, я получаю сообщение: "../main.ts(1,25): Cannot file module 'moment'."

Если я использую, import moment = require('moment');то jspm будет работать и вводить модуль при запуске приложения, но я все еще получаю ошибку сборки. Я также пробовал:

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

Однако вместо того, чтобы улучшить проблему, она стала еще хуже. Теперь я получаю указанную выше ошибку при сборке, а также следующее:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Если я перейду к файлу, предоставленному набором символов, и добавлю внизу файла:

declare module "moment" { export = moment; }

Я могу заставить вторую ошибку исчезнуть, но мне все еще нужен оператор require, чтобы получить момент для работы с моим main.tsфайлом, и я все еще получаю первую ошибку сборки.

Мне нужно создать свой собственный .d.tsфайл на данный момент или мне не хватает какой-то части настройки?

развитие пихты
источник
1
Добавление этого обновления для всех, кто import moment, { Moment } from 'moment';const x = moment();const x: Moment = moment();
столкнется с
Ни одно из этих решений не
помогло

Ответы:

124

Обновить

Судя по всему, момент теперь предоставляет свои собственные определения типов (согласно sivabudh по крайней мере с 2.14.1 и выше), поэтому они вам не нужны typingsили вообще не нужны @types.

import * as moment from 'moment' должен загрузить определения типов, предоставленные в пакете npm.

При этом, однако, как сказано в moment / pull / 3319 # issuecomment-263752265, у команды, похоже, есть некоторые проблемы с поддержанием этих определений (они все еще ищут того, кто их поддерживает) .


Вам нужно установить momentтипизацию без --ambientфлага.

Затем включите его, используя import * as moment from 'moment'

Помощники
источник
Это сработало. Можете ли вы объяснить разницу между использованием --ambientфлага и его использованием? Я получил numeraljs для работы с окружающим флагом. Кроме того, на их главной странице npmjs.com/package/typings приводится пример с использованием флага окружения. Я не знаю, когда мне нужно / нужно использовать одно вместо другого. Благодарность!
peinearydevelopment
1
Если честно, не могу. Обычно вы используете этот --ambientфлаг для всех определений Typescript из typings/, DefinitelyTypedно momentопределение имеет странную структуру, и файлы загружаются неправильно. Если вы посмотрите на файл определения moment.d.ts, он содержит только ссылку на версию узла, которая не разрешается при загрузке (возможно, стоит открыть проблему).
Aides
По-видимому, уже есть один, связанный с этой проблемой: github.com/DefinitiTyped/DefinentyTyped/issues/8388
peinearydevelopment
1
Я заставил его работать, используя import *, поскольку момент с момента / момента b / c он был установлен как подпапка в папке node-modules.
user441058 04
1
Я использую веб-пакет и версию 2.17.1, но все еще не могу заставить его работать. Я пробовал: import * as moment from 'moment'; и импортировать * как момент из "момент / момент"; и не работает!
Mohy Eldeen
59

Вам необходимо отдельно импортировать функцию moment () и класс Moment в TS.

Я нашел заметку в документах машинописного текста здесь .

/ * ~ Обратите внимание, что модули ES6 не могут напрямую экспортировать вызываемые функции
* ~ Этот файл следует импортировать в стиле CommonJS:
* ~ import x = require ('someLibrary');

Таким образом, код для импорта моментальных js в машинописный текст на самом деле выглядит так:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Коби
источник
1
Хороший ответ, поскольку он показывает разницу между типом и функцией. Благодарность!
Jelle den Burger
не могу найти имя 'require'
закодированный контейнер
4
Теперь это можно использовать как, import * as moment from 'moment';а затем использовать moment.Momentдля набора текста.
Meteor
Для меня сработало: import moment = require ('moment');
Тельмо Пиментел Мота
На самом деле вы также можете использовать moment.Momentинтерфейс непосредственно из пространства именmoment
HalfWebDev
20

Не уверен, когда это изменилось, но с последней версией машинописного текста вам просто нужно использовать, import moment from 'moment';а все остальное должно работать как обычно.

ОБНОВИТЬ:

Похоже, недавний момент исправил их импорт. По крайней мере, 2.24.0вы захотите использоватьimport * as moment from 'moment';

NSjonas
источник
5
import * as moment from 'moment'не будет работать с машинописным текстом, но import moment from 'moment'работает.
Стюарт Макинтайр
Он работает, но я получаю время по Гринвичу 0, но мне нужно местное время, которое не работает. Я также пытаюсь использовать moment (). Utc (). Format (), но он возвращает тот же результат.
kbhaskar
@kbhaskar в последней версии на момент исправления импорта. См. Обновленный ответ
NSjonas
1
Я думаю, что это почти все. Единственный дополнительный шаг, который мне нужно было сделать, это добавить esModuleInteropнабор trueв мою конфигурацию, что я получил из этого ответа . Спасибо.
Марк Бирбек,
14

через набор текста

Moment.js теперь поддерживает TypeScript в v2.14.1.

См .: https://github.com/moment/moment/pull/3280


Прямо

Возможно, это не лучший ответ, но это метод грубой силы, и он работает для меня.

  1. Просто скачайте сам moment.jsфайл и включите его в свой проект.
  2. Например, мой проект выглядит так:

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

  1. А вот пример исходного кода:

``

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. Просто nodeбеги main.js.
Шивабудх
источник
Да, я подтверждаю, что это верный ответ. Работал как шарм.
Capy
Когда я пытаюсь сделать это с помощью npm i @ types / moment, я получаю сообщение об ошибке: Ошибка TypeScript: src \ app.ts (1,1): ошибка TS7038: невозможно вызвать или создать импорт в стиле пространства имен, что приведет к сбой во время выполнения. на tsc -v 2.7.2
GONeale
2

Я только что заметил, что ответ, за который я проголосовал и прокомментировал, неоднозначен. Так что у меня сработало именно следующее. Сейчас я использую Moment 2.26.0и TS 3.8.3:

В коде:

import moment from 'moment';

В конфигурации TS:

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

Я создаю как для CommonJS, так и для EMS, поэтому эта конфигурация импортируется в другие файлы конфигурации.

Понимание приходит из этого ответа, который относится к использованию Express. Я решил, что это стоит добавить сюда, чтобы помочь любому, кто ищет в отношении Moment.js, а не что-то более общее.

Марк Бирбек
источник
тогда вы можете использовать moment()как обычно вместоmoment.default()
xinthose
0

1. момент установки

npm install moment --save

2. протестируйте этот код в своем машинописном файле.

import moment = require('moment');

console.log(moment().format('LLLL'));
выносливая лутула
источник
1
Это неправильный способ импортировать модуль в машинописный текст. Пожалуйста, обновите свой ответ. Обратитесь к этому для подтверждения: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

Все еще не работает? Попробуйте удалить @types/moment.

Итак, я удалил @types/momentпакет из package.jsonфайла, и он работал с использованием:

import * as moment from 'moment'

Более новые версии momentне требуют @types/momentпакета, так как типы уже включены.

Бен Виндинг
источник