2017-02-14 8 views
13

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

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

Я добавил другие файлы определения машинописи с помощью:

npm install --save-dev @types/jquery 

... Но, выше кажется, что неправильно выбор для момента. При использовании вышеуказанной команды (но заменить «момент» для «JQuery»), ридми файл загружается, который говорит:

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

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

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

Но, машинопись дает мне предупреждение:

не удается найти имя «момент»

+1

Вы писали руководство пользователя [moment typescript] (http://momentjs.com/docs/#/use-it/typescript/)? Это покрывает ваш usecase? – VincenzoC

+0

Я не уверен, что он охватывает мой прецедент. Я пытался. Результатом является то, что в созданный JavaScript добавляется инструкция require. Но я стараюсь, если возможно, избегать заявления о необходимости. – edt

ответ

6

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

export * from 'moment' 
export as namespace moment 

и включить эту папку в tsconfig.json:

{ 
    include: [ 
    "custom-typings" 
    ] 
} 
+0

Мне нравится это решение, поскольку оно не связано с редактированием файлов up-stream. – dtabuenc

+0

По какой-то причине после добавления свойства «include» в файл tsconfig.json VS перестает компилировать мои файлы при сборке. Это происходит при сохранении файла .ts, но не при создании проекта, и это создает проблемы при публикации. Пошел с решением @dtabuenc. –

+0

У вас есть несколько файлов tsconfig?Как вы говорите, «это происходит при сохранении файла .ts», это означает, что он работает. Возможно, вы просто не включили «настраиваемые типы» в конфигурацию сборки. – unional

4

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

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

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

export as namespace moment; 

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

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

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

+0

Это сработало для меня. Moment [имеет открытый PR] (https://github.com/moment/moment/pull/3688), чтобы решить эту проблему. –

+1

Я бы также посмотрел на ответ @unional, поскольку это лучший/менее навязчивый способ добиться того же. – dtabuenc

6

TL; DR;

Добавить moment.d.ts (link) в проекте с сайта момент 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 заявления в конце файла определения, «превращает» его в внутреннем - файл декларации модуля - но глобальный характер.

2

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

import * as moment from 'moment'; 


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

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

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

+1

Это простая копия документации, которая, как я подозреваю, следует за OP, и предполагает, что OP использует ES6 или CommonJS. –

+0

Да, я нашел его только в документации. –