2017-02-14 1181 views
20

在過去的幾個小時裏,我一直在努力解決這個問題,我似乎無法在互聯網上找到任何可以清楚地解釋這個,據說是簡單概念的東西。如何爲TypeScript配置自定義全局接口(.d.ts文件)?

我目前正在使用Webpack2和TypeScript的ReactJS項目。除了一件事情之外,一切都完美運行 - 我無法找到一種方法將我自己寫入單獨文件的接口移動到整個應用程序中。

爲了原型設計的目的,我最初在使用它們的文件中定義了接口,但最終我開始添加一些在多個類中需要的,這就是所有問題開始時的情況。無論我對我的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,我把我的自定義在./typings.d.ts文件,包括它在typeRoots

我用TypeScript 2.1.6和2.2.0對它進行了測試,兩者都不起作用。這一切讓工作的

一種方法是將我的typings目錄爲src,然後import {IMyInterface} from 'typings/blah'但並不覺得我的權利,因爲它不是我需要使用。我希望這些接口在我的應用程序中「神奇地」可用。

編輯: 下面是一個示例app.d.ts文件:

interface IAppStateProps { 
} 

interface IAppDispatchProps { 
} 

interface IAppProps extends IAppStateProps, IAppDispatchProps { 
} 

我需要export他們也許declare?我希望我不必將它們包裝在命名空間中!

回答

34

「神奇可用接口」或全局類型非常不鼓勵,應該主要留給傳統。此外,您不應該爲您正在編寫的代碼使用環境聲明文件(例如d.ts文件)。這些是爲了代替外部非打字稿代碼(基本上將打字稿類型填入js代碼中,以便您可以更好地將其與javascript集成)。

對於您編寫的代碼,您應該使用普通的.ts文件來定義您的接口和類型。

儘管不鼓勵全局類型,但您的問題的答案是在Typescript中有兩種類型的.ts文件。這些被稱爲scriptsmodules

任何在script將是全球性的。因此,如果您在腳本中定義接口,則它將在整個應用程序中全局可用(只要腳本通過///<reference path="">標記或通過files:[]includes:[]或默認**/*.ts在您的tsconfig.json中包含在編譯中。

其他文件類型是'模塊',並且module中的任何內容對模塊都是私有的。如果您從模塊中導出任何內容,則其他模塊將選擇導入其他模塊。

什麼使.ts文件成爲「腳本」或「模塊」?那麼....如果你在文件的任何地方使用import/export,那麼這個文件就變成了一個「模塊」。如果沒有import/export語句,那麼它是一個全局腳本。

我的猜測是您無意中使用在聲明importexport並把它做成一個模塊,這竟然所有的接口,以私人該模塊內。如果你希望它們是全局的,那麼你會確保你沒有在你的文件中使用導入/導出語句。

+0

你絕對正確!原來我的問題是(如你所建議的),我從其他文件導入類/接口到我的聲明文件。只要我刪除這些導入,並只留下乾淨的'interface Foo {}'聲明一切正常。 根據globals - 我完全明白爲什麼有聲明是神奇的可用是一種不好的做法,並且正在考慮切換到自定義模塊(實際上已嘗試'聲明模塊MyApp {export interface Foo {}}'並且可以通過執行成功導入它'從'MyApp''導入{{Foo}),但現在魔術爲我:) – Andris

+0

謝謝,你的回答很多! – jasonslyvia