如何导出和导入types定义?

我一直在使用TypeScript一段时间,模块系统仍然是我的一个谜。

我有这个types定义文件(appComponents.d.ts):

/// <reference path="./authentication/API.d.ts"/> import express = require('express'); declare module appComponents { export interface IComponents { application: express.Application; authenticationService: MyApp.IAuthenticationService; // and so on ... } } 

和这个文件(index.ts):

 /// <reference path="./appComponents.d.ts"/> import express = require('express'); import mssql = require('mssql'); function initComponents(): appComponents.IComponents { // Components initialized here ... } 

两个问题:

  1. 为什么我必须使用

    import express = require('express');

    代替

    /// <reference path="./path/to/definitely-typed/express/express.d.ts"/>

    避免error TS2095: Could not find symbol 'express'. ? 毕竟,这只是一个types定义文件,它不生成JavaScript,这取决于另一个不生成JavaScript的types定义文件中的types。

  2. 为什么index.ts会导致error TS2095: Could not find symbol 'appComponents'. ? 而当我这样做:

    import appComponents = require('./appComponents');

    为什么会导致error TS2094: The property 'IComponents' does not exist on the value of type 'appComponents'.

使用TypeScript 0.9.7.0。

  1. )为什么我必须使用

import express = require('express'); 而不是/// <reference path="./path/to/definitely-typed/express/express.d.ts"/>

其实你需要使用两个

 /// <reference path="./path/to/definitely-typed/express/express.d.ts"/> import express = require('express'); 

您可能在API.d.ts有参考,或者只是在您的visual studio项目中包含express.d.ts

它是如何工作的 : https : //github.com/borisyankov/DefinitelyTyped/blob/master/express/express.d.ts#L15包含declare module "express" {这告诉打字机要给(在这个文件中export所有东西: https://github.com/borisyankov/DefinitelyTyped/blob/master/express/express.d.ts当有&#x4EBA;import / requireimport express = require('express')这些被称为打字机中的外部模块 ,可以amd / commonjs

为什么index.ts会导致错误TS2095:无法find符号'appComponents'

因为您正在声明一个内部模块并尝试将其作为外部模块导入。

PS:关于外部/内部模块的video: http : //www.youtube.com/watch?v = KDrWLMUY0R0 & hd = 1

UPDATE

你说我的问题中的一个模块是一个内部模块:

只是FYI: declare module appComponents {使appComponents一个内部模块。 你应该declare module "appComponents" {如果你想声明一个外部模块并使用import appComponents = require('appComponents'); 但是不要。 它不是你想要的。

为什么index.ts会导致错误TS2095:无法find符号“appComponents”。

由于appComponents.d.ts进行import因此也成为外部模块。 您应该将declare module appComponents {等等移到它自己的文件中, declare module appComponents {需要外部模块,然后使用///<reference

这是什么解决了我的问题(#2):

不要创build.d.ts文件作为分离接口和实现类的一种方式。 相反,在.ts文件中定义interface 。 当一个类和它实现的接口在不同的文件中时, requireclass模块interface模块。 对于不能由类实现的接口,也就是用于强typesvariables的接口,也要这样做。

例:

 // IAppComponents.ts /// <reference path="../DefinitelyTyped/express/express.d.ts"/> import express = require('express'); import IAuthenticationService = require('./services/IAuthenticationService') interface IAppComponents { application: express.Application; authenticationService: IAuthenticationService; } export = IAppComponents; 
 // IAuthenticationService.ts import ILoginCallback = require('./ILoginCallback'); import ILogoutCallback = require('./ILogoutCallback'); interface IAuthenticationService { login(user: string, pass: string, callback: ILoginCallback) void; logout(sessionToken: string, callback: ILogoutCallback): void; } export = IAuthenticationService; 
 // AuthenticationService.ts import IAuthenticationService = require('./IAuthenticationService'); import ILoginCallback = require('./ILoginCallback'); import ILogoutCallback = require('./ILogoutCallback'); // We can't import this, because it's a js module with no matching type definition. var mssql = require('mssql'); class AuthenticationService implements IAuthenticationService { login(user: string, pass: string, callback: ILoginCallback): void { // Implementation goes here ... } logout(sessionToken: string, callback: ILogoutCallback): void { // Implementation goes here ... } } export = AuthenticationService; 

这种方法的工作原理很简单:即使.ts文件只包含接口,TypeScript编译器.d.ts为每个.ts (但不包括.d.ts )文件生成.js文件,从而生成空的.js文件。 我现在可以忍受,但是我希望TypeScript团队有一天能做些什么。