我正在为一个相当大(800+文件)的AMD JavaScript库编写TypeScript Type定义。您可以在下面看到一个代码段:
declare namespace myjslib {
namespace shape {
interface Shape {
contains(p: Point): boolean;
}
class Point implements Shape {
constructor(x: number, y: number);
contains(p: Point): boolean;
}
class Circle implements Shape {
constructor(p: Point, radius: number);
contains(p: Point): boolean;
}
}
}
declare module "myjslib/shape/Point" {
export = myjslib.shape.Point;
}
declare module "myjslib/shape/Circle" {
export = myjslib.shape.Circle;
}
我在命名空间中定义了类型。 (注意myjslib不是库的真实名称:)):
Point
和Circle
等类名可能会发生冲突。 然后我尝试编写一个依赖于此类型定义文件的TypeScript应用程序:
/// <reference path="./myjslib.d.ts" />
import Point = require("myjslib/shape/Point");
import Circle = require("myjslib/shape/Circle");
import Circ = myjslib.shape.Circle;
let c1 = new Circle(new Point(1,3), 20);
let c2: Circle;
let c3: myjslib.shape.Circle;
let c4: Circ;
c1.contains(new Point(5,6));
c2 = c1;
c3 = c1;
c4 = c1;
编译此打字稿文件时,会生成正确的JavaScript代码:输出有效AMD,可以加载现成的AMD模块加载器,并可以优化为单个JavaScript文件等。
但是,TypeScript编译器会在c2
变量的声明中生成错误:
>tsc --module amd app.ts
app.ts(8,9): error TS2304: Cannot find name 'Circle'.
显然,可以引用导入的Circle
来创建一个圆圈。 import语句有效,因为您可以访问Circle
构造函数。但是,在声明该类型的变量时,Circle
不能用作类型注释。也可以使用类型的完全限定名称:编译器不会抱怨c3
声明,因此编译器会找到并使用typescript定义文件。另外,如果我创建了一个别名Circ
,那么类型系统就像一个魅力(c4
的声明)。
我的理解是import Circle = require("myjslib/shape/Circle")
语句也导入了类型信息。要在TypeScript Deep Dive中使用术语,我希望Circle
在该模块的类型声明空间中可用,但事实并非如此。类型信息通过TypeScript定义文件加载:myjslib
命名空间可用。
总而言之:我必须编写代码,我必须使用import来创建特定类的实例,但如果我想声明该类的变量,我必须使用完全限定的类型名称。这使编写代码非常混乱(和冗长)。有没有办法解决?这是预期的行为,还是我遇到了TypeScript编译器错误?