【发布时间】:2014-01-09 13:31:30
【问题描述】:
我正在尝试为 Bluebird 编写一个 CommonJS 声明文件,这是一个直接导出通用 Promise 类的 Promise 库。但是,该库还将其他几个泛型类导出为静态成员 (PromiseInspection),并且似乎无法使用 typescript 对其进行建模。
编辑:使用示例,说明模块的导出类如何工作:
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
3。尝试直接从模块中导出构造函数
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'表达式”
Link to the actual, work-in-progress bluebird.d.ts - 这个当前污染了全局命名空间(使用解决方案 4)
有没有更好的方法来做到这一点,还是我遇到了语言限制?
【问题讨论】:
标签: class generics module export typescript