我一直在使用TypeScript,模块系统对我来说仍然是一个谜。
我有这个类型定义文件(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'.
?毕竟,这只是一个类型定义文件,它不会生成任何JavaScript,具体取决于另一个不生成JavaScript的类型定义文件中的类型。
为什么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。
答案 0 :(得分:3)
- )为什么我必须使用
醇>
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:找不到符号'appComponents'
因为您要声明内部模块并尝试将其作为外部模块导入。
PS:关于外部/内部模块的视频:http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1
<强>更新强>
你说我问题中的一个模块是内部模块:
仅供参考:declare module appComponents {
使appComponents
成为内部模块。如果要声明外部模块并使用declare module "appComponents" {
,则应该import appComponents = require('appComponents');
但不要。它不是你想要的。
为什么index.ts导致错误TS2095:找不到符号'appComponents'。?
因为appComponents.d.ts
执行import
它也成为外部模块。您应该将declare module appComponents {
等移动到没有外部模块的文件中,然后使用///<reference
答案 1 :(得分:0)
这就解决了我的问题(#2):
不要创建.d.ts
文件作为分离接口和类实现的方法。相反,在interface
个文件中定义.ts
。当一个类及其实现的接口位于不同的文件中时,require
interface
模块中的class
模块。这也适用于不由类实现的接口,即用于强类型变量的接口。
示例:
// 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;
这种方法很有用,但有一点需要注意:TypeScript编译器为每个.js
(但不是.ts
)文件生成.d.ts
个文件,即使.ts
文件包含只有接口,导致生成空.js
个文件。我现在可以忍受这种情况,但我希望有一天TypeScript团队能够做到这一点。