2017-02-14 763 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

相关问题