如何导出和导入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 ... }
两个问题:
-
为什么我必须使用
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。 -
为什么
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。
- )为什么我必须使用
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当有人import / require
即import 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
。 当一个类和它实现的接口在不同的文件中时, require
从class
模块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团队有一天能做些什么。