Подтвердить что ты не робот

Как использовать файл определения Moment.js TypeScript, если мой сайт уже использует moment.min.js?

Я в процессе преобразования веб-сайта для использования TypeScript, и я конвертирую только один из многих файлов JavaScript в TypeScript. Все страницы моего сайта уже ссылаются на moment.js, например:

<script src="/scripts/moment.min.js"></script>

Я добавил другие файлы определения TypeScript, используя:

npm install --save-dev @types/jquery

... Но вышеизложенное кажется неправильным выбором для момента. Когда я использую приведенную выше команду (но заменяю "момент" для "jquery" ), загружается файл readme, который гласит:

Это определение типов заглушек для Moment (https://github.com/moment/moment). Moment предоставляет собственные определения типов, поэтому вам не нужны установленные @типов/моментов!

В качестве решения я попытался сохранить файл moment.d.ts из своего репозитория GitHub и ссылаться на него в файле TypeScript так:

///<reference path="../../Scripts/typeDeclarations/moment.d.ts"/>
var now:any = moment.utc();

Но, TypeScript дает мне предупреждение:

Не удается найти имя "момент"

4b9b3361

Ответ 1

Один из способов сделать это - создать пользовательский ввод, например. custom-typings/moment.d.ts:

export * from 'moment'
export as namespace moment

И включите эту папку в свой tsconfig.json:

{
  include: [
    "custom-typings"
  ]
}

Ответ 2

TL; DR;

Добавьте moment.d.ts (ссылка) в ваш проект с момента сайта github и комментарий последняя строка

 //export = moment;

Я создал мини-тестовый проект, чтобы доказать это, и это работает для меня.

Структура проекта

--
  |
  -typings/
     -moment/
       -moment.d.ts   <-- //export = moment; commented out
  -typescript/
     -main.ts
  -tsconfig.json

Содержимое как typings, так и typescript является частью цели компиляции, то есть не исключено в tsconfig.json, которое выглядит как

{
    "compilerOptions": {
        "target": "es5",
        "declaration": false,
        "noImplicitAny": true,
        "removeComments": true,
        "outDir": "dist",
        "jsx": "react",
        "sourceMap": true,
        "experimentalDecorators": true
    },
    "compileOnSave": true,
    "exclude": [
        "node_modules",
        "dist"
    ]
}

Файл main.ts содержит

const now: moment.Moment = moment.utc();

и компилирует... Как и ожидалось, моя IDE дает мне автозаполнение из файла определения. (нет необходимости в тегах ///<reference - вы должны избегать их в любом случае)

Удаление оператора export в конце файла определения "преобразует" его в файл декларации внутреннего, но глобального модуля.

Ответ 3

К сожалению, объявления типа momentjs записываются в чисто модульном синтаксисе. Это связано с тем, что в эти дни многие люди используют npm для приобретения js-пакетов, а затем используют загрузчики модулей, такие как Webpack или Browserify, для объединения модулей npm в формате, который можно использовать для браузера.

В вашем случае вы не используете модули, а просто полагаетесь на импорт сценариев браузера в глобальном контексте. Чтобы поддержать это, авторы файлов определений должны были сделать определение в соответствии с руководящими принципами UMD, что позволяет написать определение так, чтобы они поддерживали модульное и глобальное использование среды.

К счастью, вам очень легко добавить это в свою копию определений. Просто добавьте следующую строку в начало moment.d.ts

export as namespace moment;

Что это означает, в основном говорят, что когда вы ссылаетесь на moment.d.ts с директивой tripple-slash, он будет предоставлять все экспортированное из модуля под глобальным пространством имен с именем "moment".

Это означает, что теперь должна быть глобальная переменная moment, доступная в глобальном контексте, и вы больше не увидите ошибку Cannot find the name 'moment'.

Это должно быть все, что вам нужно сделать.

Ответ 4

Начиная с версии 2.13.0, Moment содержит файл определения typescript. Поэтому, если вы используете эту версию, вы можете сделать следующее:

import * as moment from 'moment';


let now = moment().format('LLLL');

Примечание. Если у вас возникли проблемы с импортом момента, попробуйте добавить "allowSyntheticDefaultImports": true в compilerOptions в ваш файл tsconfig.json.

Для справки посетите официальный doc.