我正在尝试为Bluebird编写一个CommonJS声明文件,它是一个直接导出通用Promise类的Promise库。但是,该库还将几个其他通用类作为静态成员导出(PromiseInspection),似乎无法使用TypeScript进行建模。
编辑:使用示例,以说明模块导出类的工作原理:
同样失败,但这次私有类型是Promise。
尝试直接从模块导出构造函数。
编辑:使用示例,以说明模块导出类的工作原理:
import Promise = require('bluebird');
var promise:Promise<number> = Promise.cast(5);
var x:Promise.PromiseInspection<number> = promise.inspect();
我将尝试几种策略 - 下面是简化的示例:
1. 显而易见的方法
declare module "bluebird" {
class PromiseInspection<T> {
// ...
}
class Promise<T> {
PromiseInspection: typeof PromiseInspection; // error
constructor<T>();
inspect():PromiseInspection<T>; // error
static cast<U>(value:U):Promise<U>;
// ...
}
export = Promise;
}
出错并提示“无法将私有类型PromiseInspection用作公共属性”
2. 使用静态接口
declare module "bluebird2" {
interface PromiseInspection<T> {
// ...
}
interface Promise<T> {
constructor<T>();
inspect():PromiseInspection<T>;
}
interface PromiseStatic {
new<T>();
PromiseInspection:typeof PromiseInspection;
cast<U>(value:U):Promise<U>; // error
}
export = PromiseStatic;
}
同样失败,但这次私有类型是Promise。
尝试直接从模块导出构造函数。
declare module "bluebird3" {
export interface PromiseInspection<T> {
// ...
}
export interface Promise<T> {
constructor<T>();
inspect():PromiseInspection<T>;
}
export new<T>(); // syntax error
export function cast<U>(value:U):Promise<U>;
}
这个方法基本可行,但是用构造函数的方式实现是不可能的。
4. 污染命名空间的方式(可行,但有缺陷)
interface PromiseInspection<T> {
// ...
}
interface Promise<T> {
constructor<T>();
inspect():PromiseInspection<T>;
}
declare module "bluebird4" {
interface PromiseStatic {
new<T>():Promise<T>;
PromiseInspection: typeof PromiseInspection;
cast<U>(value:U):Promise<U>;
}
export = PromiseStatic;
}
虽然可行,但它会使用Promise和PromiseInspection污染全局命名空间。这 也许 可以,但我宁愿避免它,因为在CommonJS中,这通常被认为是不可接受的。
5. 使用声明合并(可以解决90%的问题...)
declare module "bluebird5" {
module Promise {
export interface PromiseInspection<T> {
value(): T;
// ...
}
export
function cast<U>(value: U): Promise<U> ;
}
class Promise<T> {
new <T> (): Promise <T> ;
inspect(): Promise.PromiseInspection <T> ;
}
export = Promise;
}
快要完成了 - 但现在我不允许用interface Promise<T>
替换class Promise<T>
,这使得Promise<T>
无法扩展。如果我尝试这样做,以下代码会出现问题:
import Promise = require('bluebird');
var x = new Promise<number>();
x.inspect().value().toExponential();
出现错误“无效的'new'表达式”
链接到实际的、正在进行中的bluebird.d.ts - 这个文件当前会污染全局命名空间(使用解决方案4)
是否有更好的方法来处理这个问题,或者我碰到了语言的限制?