2017-02-14 48 views
20

Я борется с этой проблемой в течение последних нескольких часов, и я просто не могу найти что-либо в Интернете, которое бы четко объясняло это, предположительно, простое понятие.Как настроить пользовательские глобальные интерфейсы (файлы .d.ts) для TypeScript?

В настоящее время я работаю над проектом ReactJS, который использует Webpack2 и TypeScript. Все работает отлично, кроме одного - я не могу найти способ переместить интерфейсы, которые я написал себе в отдельные файлы, чтобы они были видны для всего приложения.

Для прототипирования вначале у меня были интерфейсы, определенные в файлах, которые их используют, но в конце концов я начал добавлять некоторые из них, которые были необходимы в нескольких классах, и вот тогда все проблемы начались. Независимо от того, какие изменения я внес в мой tsconfig.json, и независимо от того, где я помещал файлы, моя IDE и Webpack жалуются на то, что не могут найти имена (Could not find name 'IMyInterface').

Вот мой текущий tsconfig.json файл:

{ 
    "compilerOptions": { 
    "baseUrl": "src", 
    "outDir": "build/dist", 
    "module": "commonjs", 
    "target": "es5", 
    "lib": [ 
     "es6", 
     "dom" 
    ], 
    "typeRoots": [ 
     "./node_modules/@types", 
     "./typings" 
    ], 
    "sourceMap": true, 
    "allowJs": true, 
    "jsx": "react", 
    "moduleResolution": "node", 
    "rootDir": "src", 
    "forceConsistentCasingInFileNames": true, 
    "noImplicitReturns": true, 
    "noImplicitThis": true, 
    "noImplicitAny": false, 
    "strictNullChecks": true, 
    "suppressImplicitAnyIndexErrors": true, 
    "noUnusedLocals": true 
    }, 
    "exclude": [ 
    "node_modules", 
    "build", 
    "scripts", 
    "acceptance-tests", 
    "webpack", 
    "jest", 
    "src/setupTests.ts" 
    ], 
    "types": [ 
    "typePatches" 
    ] 
} 

Как вы можете видеть, мой tsconfig.json находится в корне директории проекта, весь источник в ./src, я поместил мои пользовательские .d.ts файлов в ./typings и включил его в typeRoots.

Я тестировал его с помощью TypeScript 2.1.6 и 2.2.0 и не работает.

Один из способов получить все это работать, чтобы переместить мой typings каталог в src и затем import {IMyInterface} from 'typings/blah' но не чувствует себя хорошо для меня, как это не то, что мне нужно использовать. Я хочу, чтобы эти интерфейсы были «магически» доступны во время моего приложения.

Edit: Вот пример app.d.ts файла:

interface IAppStateProps { 
} 

interface IAppDispatchProps { 
} 

interface IAppProps extends IAppStateProps, IAppDispatchProps { 
} 

Мне нужно export их или, может быть, declare ли? Надеюсь, мне не нужно обертывать их в пространство имен?

ответ

34

«Магически доступные интерфейсы» или глобальные типы сильно обескуражены и в основном должны быть оставлены на прежнем уровне. Кроме того, вы не должны использовать файлы декларации окружающей среды (например, d.ts файлов) для кода, который вы пишете. Они предназначены для того, чтобы встать на место внешнего кода, отличного от машинописных (по сути, заполнять типы типов ввода в js-код, чтобы вы могли лучше интегрировать его с javascript).

Для кода, который вы пишете, вы должны использовать простые файлы .ts для определения ваших интерфейсов и типов.

В то время как глобальные типы обескуражены, ответ на ваш вопрос заключается в том, что в машинописном машинописном файле есть два типа файлов .ts. Они называются scripts и modules.

Все, что угодно в script будет глобальным. Поэтому, если вы определяете свои интерфейсы в сценарии, он будет доступен по всему миру в вашем приложении (пока скрипт будет включен в компиляцию либо через теги ///<reference path="">, либо через files:[] или includes:[] или по умолчанию **/*.ts в вашем tsconfig.json.

Другой тип файла - «модуль», и все, что угодно в module, будет закрыто для модуля. Если вы экспортируете что-либо из модуля, он будет доступен для других модулей, если эти другие модули захотят его импортировать.

Что делает файл .ts «сценарием» или «модулем»? Ну ... если вы используете import/export в любом месте файла, этот файл становится «модулем». Если нет операторов import/export, это глобальный скрипт.

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

+0

Вы абсолютно правы! Оказалось, что моя проблема (как вы сказали) заключалась в том, что я импортировал классы/интерфейсы из других файлов в файлы декларации. Как только я удалил эти импортные файлы и оставил только чистые '' '' '' '' '' '' 'декларации интерфейса, все сработало. В соответствии с глобалами - я полностью понимаю, почему объявления с магической доступностью являются плохой практикой, и я рассматриваю возможность переключения на пользовательский модуль (фактически попробовал «объявить модуль MyApp {export interface Foo {}}» и смог успешно импортировать его, выполнив 'import {{Foo} из 'MyApp''), но пока волшебство работает для меня :) – Andris

+0

Спасибо, ваши ответы много! – jasonslyvia