我正在尝试为minimal-bit-array
创建声明文件。这就是它的本质:
function A() { this.data = 'foo'; }
A.prototype.serialize = function() { /* ... */ };
module.exports = A;
module.exports.deserialize = function(x) { /* ... */ };
如何输入?
答案 0 :(得分:4)
这是:
declare module "a" {
namespace A {
export interface X { /* ... */ }
}
interface A {
data: string;
serialize(): A.X;
}
const A: {
new (): A;
deserialize(obj: A.X): A;
};
export = A;
}
这种反直觉的namespace
+ interface
+ const
三明治成功合并为TypeScript可以理解的明确的 something 。消费示例:
import * as A from "a";
const a: A = new A();
const d: A['data'] = a.data;
const x: A.X = a.serialize();
const amazing = A.deserialize(x);
为什么三明治?
从理论上讲,namespace A
和const A
正在做同样的事情:描述module.exports
的{{1}}。但构造函数 - a
- 只能在接口中声明,而TypeScript唯一的东西 - new (): A
- 只能在命名空间中定义。这就是为什么两者同时需要的原因。否则无法导出interface X
。至少据我所知。值得庆幸的是,TypeScript知道如何合并它们。
同时,interface X
只是一种便利。当在期望类型的上下文中的代码中的某处引用interface A
时,这就是您获得的接口。另外两个 - A
和namespace
- 不是类型,所以没有歧义。可以将其保留在const
中,但是,如果这太神奇了,请将其引用为namespace A
。
在2.8上测试。
稍微清洁的方法:
A.A
类很适合这种情况。这在语义上也等同于原始方法,因为类在函数之上基本上是语法糖。检查this playground以查看上述类的实现将被转换为什么。
在2.8上测试。