首先,我对TS非常陌生,在我阅读期间 http://www.typescriptlang.org/Handbook我试图了解混合类型接口的工作原理。
在TS的例子中:
interface ICounter {
(start: number): string;
interval: number;
reset(): void;
}
var c: ICounter;
c(10);
c.reset();
c.interval = 5.0;
所以,问题是当我尝试使用这个接口编写一个类时,问题就在于:
(start: number): string;
首先我认为这一行代表了一个试图创建的函数:
class Test implements ICounter {
interval: number;
reset(): void { }
start(start: number): string {
return "";
}
}
但这表明"类型测试和ICounter有不兼容的签名",所以我在这里失踪了什么?我认为接口应该对类和变量的工作方式相同。
答案 0 :(得分:1)
ICounter
表示具有两个属性的函数 - interval
和reset
。
界面中的这一行......
(start: number): string;
...描述了一种调用函数的方法。它在示例中显示为:
c(10)
其他行描述了函数的属性 - interval
和reset
。
c.reset();
c.interval = 5.0;
如手册中所述,这用于表示执行此操作的JavaScript库。例如,上面的代码可能代表以下JavaScript代码:
function counter(start) {
alert(start);
return "some string";
}
counter.reset = function() { alert('reset called'); };
counter.interval = 1;
除此之外,请注意您描述的类可以通过以下界面表示:
interface ITest {
interval: number;
reset: () => void;
start: (start: number) => string;
}
答案 1 :(得分:0)
class
表示您将通过new
运算符创建实例。 new
创建object
,而不是function
,因此无法实现类,哪些实例可以作为函数调用。你可以这样做:
interface ICounterObject {
interval: number;
reset(): void;
}
interface ICounter extends ICounterObject {
(start: number): string;
__proto__: ICounterObject;
}
class Test implements ICounterObject {
static createCounter(): ICounter {
var counter = <ICounter>function (start: number): string {
return "";
};
counter.__proto__ = Test.prototype;
return counter;
}
interval: number;
reset(): void { }
}
注意,__proto__来自ES6,但ES5浏览器支持事实上的。如果你想使用函数原型成员(例如call
和apply
)混合原型:
function mixWithFunc<T extends Function>(obj: { __proto__?}, func: T) {
var objProto = <{ constructor }>obj.__proto__;
var objClass = <{ __mixedProto__ }>objProto.constructor;
var proto = <typeof obj>objClass.__mixedProto__;
if (!proto) {
proto = {};
proto.__proto__ = objProto;
['call', 'apply', 'bind'].forEach(p => proto[p] = Function.prototype[p]);
objClass.__mixedProto__ = proto;
}
(<typeof obj>func).__proto__ = proto;
Object.getOwnPropertyNames(obj).forEach(p => func[p] = obj[p]);
return func;
}
interface ICounter extends Counter {
(start: number): string;
}
class Counter {
static create() {
var self: ICounter = mixWithFunc(
new Counter(),
<ICounter>function (start: number) {
return "started with interval: " + self.interval;
});
return self;
}
interval = 1000;
reset() { this.interval = 0; }
}
当然,你可以只为你的每个函数实例添加成员而不是原型。