TypeScript 2: пользовательские типы для нетипизированного модуля npm
после попытки предложений, опубликованных в других местах, я не могу получить проект typescript, который использует нетипизированный модуль NPM. Ниже приведен минимальный пример и шаги, которые я пробовал.
для этого минимального примера мы сделаем вид, что lodash не имеет существующих определений типов. Таким образом, мы будем игнорировать пакет @types/lodash и попробуйте вручную добавить его typings file lodash.d.ts в нашем проекте.
структура
- папки node_modules
- лодашь
- src
- фу.ТС
- typings
- custom
- лодашь.д.ТС
- глобальные
.д.ТС
- custom
далее, файлы.
File foo.ts
///<reference path="../typings/custom/lodash.d.ts" />
import * as lodash from 'lodash';
console.log('Weeee');
File lodash.d.ts копируется непосредственно из исходной @types/lodash пакета.
File index.d.ts
/// <reference path="custom/lodash.d.ts" />
/// <reference path="globals/lodash/index.d.ts" />
File package.json
{
"name": "ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"typings": "./typings/index.d.ts",
"dependencies": {
"lodash": "^4.16.4"
},
"author": "",
"license": "ISC"
}
File tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"jsx": "react",
"module": "commonjs",
"sourceMap": true,
"noImplicitAny": true,
"experimentalDecorators": true,
"typeRoots" : ["./typings"],
"types": ["lodash"]
},
"include": [
"typings/**/*",
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
File typings.json
{
"name": "TestName",
"version": false,
"globalDependencies": {
"lodash": "file:typings/custom/lodash.d.ts"
}
}
как вы можете видеть, я пробовал много различных способов импорта типов:
- путем прямого импорта его в
foo.ts
- на
typingsнедвижимость вpackage.json
- С помощью
typeRootsintsconfig.jsonфайлtypings/index.d.ts
- С помощью явной
typesнаtsconfig.json
- , включая на
tsconfig.json
- сделав заказ и под управлением
typings install
тем не менее, когда я запускаю Typescript:
E:tempts>tsc
error TS2688: Cannot find type definition file for 'lodash'.
что я делаю не так?
2 ответов:
к сожалению, эти вещи в настоящее время не очень хорошо документированы, но даже если вы смогли заставить его работать, давайте рассмотрим вашу конфигурацию, чтобы вы поняли, что делает каждая часть и как она связана с тем, как typescript обрабатывает и загружает типизацию.
сначала давайте рассмотрим ошибку, которую вы получаете:
error TS2688: Cannot find type definition file for 'lodash'.эта ошибка на самом деле не исходит от вашего импорта или ссылок или вашей попытки использовать lodash в любом месте ваших файлов ts. А это исходит из непонимания того, как использовать
typeRootsиtypesсвойства, поэтому давайте рассмотрим их немного подробнее.дело в том, что
typeRoots:[]иtypes:[]свойства заключается в том, что они не универсальные способы загрузки произвольного объявления (*.d.ts) файлов.эти два свойства напрямую связаны с новой функцией TS 2.0, которая позволяет упаковывать и загружать объявления ввода из пакеты NPM.
это очень важно понимать, что они работают только с папками в формате NPM (т. е. папка, содержащая пакета.json или .д.ТС).
по умолчанию
typeRoots- это:{ "typeRoots" : ["node_modules/@types"] }по умолчанию это означает, что typescript войдет в
node_modules/@typesпапка и попробуйте загрузить каждую подпапку, которую он находит там как npm package.важно понимать, что это произойдет, если папка не имеет структуры пакета npm.
это то, что происходит в вашем случае, и источник вашей первоначальной ошибки.
вы переключили typeRoot, чтобы быть:
{ "typeRoots" : ["./typings"] }это означает, что typescript теперь будет сканировать на подпапках и попробуйте загрузить каждую подпапку, которую он находит в качестве модуля npm.
так давайте притворимся, что вы только что
typeRootsнастройка, чтобы указать на./typingsно еще не былоtypes:[]настройки собственность. Вы, вероятно, увидите эти ошибки:error TS2688: Cannot find type definition file for 'custom'. error TS2688: Cannot find type definition file for 'global'.это так
tscсканирует ваш./typingsпапка и поиск подпапокcustomиglobal. Затем он пытается интерпретировать их как тип пакета npm, но нетindex.d.tsилиpackage.jsonв этих папках и так вы получите ошибку.теперь давайте немного поговорим о
types: ['lodash']свойства. Что это делает? По умолчанию, машинопись будет загружаться все подпапки он находит в вашемtypeRoots. Если вы укажетеtypes:свойство он будет загружать только эти конкретные подпапки.в вашем случае вы говорите это, чтобы загрузить
./typings/lodashпапка, но она не существует. Вот почему вы получаете:error TS2688: Cannot find type definition file for 'lodash'Итак, давайте подведем итог тому, что мы узнали. Typescript 2.0 представил
typeRootsиtypesдля загрузки файлов объявлений, упакованных в npm-пакетов. Если у вас есть обычай typings или один свободныйd.tsфайлы, которые не содержатся в папке после соглашений пакета npm, то эти два новых свойства не то, что вы хотите использовать. Typescript 2.0 на самом деле не меняет, как они будут потребляться. Вам просто нужно включить эти файлы в контекст компиляции одним из многих стандартных способов:
непосредственно включая его в :
///<reference path="../typings/custom/lodash.d.ts" />в том числе
./typings/custom/lodash.d.tsin вашfiles: []собственность.в том числе
./typings/index.d.tsв своемfiles: []свойство (которое затем рекурсивно включает в себя другие типы.добавлять
./typings/**наincludes:надеюсь, на основе этого обсуждения вы сможете сказать, почему изменения, которые вы с ума ваш
tsconfig.jsonзаставил все работать снова.EDIT:
одна вещь, которую я забыл упомянуть, что
typeRootsиtypesсвойства действительно полезны только для автоматическая загрузка глобальных деклараций.например, если вы
npm install @types/jqueryи вы используете tsconfig по умолчанию, тогда этот пакет типов jquery будет загружен автоматически и
$будут доступны во всех ваших скриптах без необходимости делать что-либо дальше///<reference/>илиimportThe
typeRoots:[]свойство предназначено для добавления дополнительных местоположений из где типа пакетов будет загружен frrom автоматически.The
types:[]основной вариант использования свойства-отключить автоматическое поведение загрузки (установив его в пустой массив), а затем только перечислить конкретные типы, которые вы хотите включить глобально.другой способ загрузки пакетов типа из различных
typeRootsиспользовать новый
изменить: устарело. Прочитайте ответ выше.
Я все еще не понимаю этого, но я нашел решение. Используйте следующее
tsconfig.json:{ "compilerOptions": { "target": "ES6", "jsx": "react", "module": "commonjs", "sourceMap": true, "noImplicitAny": true, "experimentalDecorators": true, "baseUrl": ".", "paths": { "*": [ "./typings/*" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts" ] }удалить
typings.jsonи все в папкеtypingsза исключениемlodash.d.ts. Также удалите все///...ссылки
Comments