接口
-
TS 中判断是否实现接口的核心原则是基于结构而不是基于名称的。即鸭子类型判断。
-
TS 中接口可以声明可选的接口属性。如
middleName?:string;
,即在属性名称后面添加?
。 -
声明只读属性示例:
readonly fullName:string;
-
TS支持函数接口如:
interface SearchFunc{ (source:string, subString:string):boolean; }
,函数的参数名称不影响函数的匹配。 -
声明支持索引存储示例:
[index:number]:string;
。 值得注意的是JS
中实际上是将索引转成字符串来表示的。也就是[index:number]
跟[index:string]
在返回100
及"100"
的索引应该是相同的对象才符合语义。
同理,由于 JS 中的obj.property
也可以通过obj["property"]
来访问,那也要求对于同样的名称obj.property
和obj["property"]
两种访问方式返回相同的对象。所以在接口中添加索引存储接口时需要注意这两点。
理解 接口类型中的构造函数接口
如果只按上面的理解的话,即我们要要求某一个类实现某一个构造函数可能会写出如下的代码:
interface ClockConstructor {
new (hour: number, minute: number);
}
class Clock implements ClockConstructor {
currentTime: Date;
constructor(h: number, m: number) { }
}
但是实际上上面的代码会报编译错误:
error TS2420: Class 'Clock' incorrectly implements interface 'ClockConstructor'.
Type 'Clock' provides no match for the signature 'new (hour: number, minute: number): any'.
这里值得说明,像 Java 这类语言是无法在接口中要求实现类必须实现某一构造函数的(Swift 可以)。
在这里我们可以这样理解,这样接口的实现的检查我们指的是类的实例。但是对于构造函数的要求则是针对类本身。所以上面的接口类型可以用来这样用:
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick();
}
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}
class DigitalClock implements ClockInterface {
constructor(h: number, m: number) { }
tick() {
console.log("beep beep");
}
}
let digital = createClock(DigitalClock, 12, 17);
接口扩展
- 新的接口可以扩展已有的接口。
- 新的接口甚至可以扩展已有的类。相当于通过组合创建一个新的类型。
如:
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class Button extends Control implements SelectableControl {
select() { }
}
兼容函数即对象的接口。
由于 JS
中函数即对象的特点。TS 可以这样声明接口:
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = <Counter>function (start: number) { };
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
类
-
TS 中类的属性,构造函数可以添加
public
,protected
,private
等访问控制关键词。 -
虽然 TS 中的自定义类型的兼容性判断是基于结构的。但是如果有
private
或
protected
属性的话,要求private
及protected
属性的继承是同源的。 -
类属性也可以添加
readonly
只读声明。 -
在构造函数的参数前添加
private
,protected
,public
,readonly
任一修饰都会将对应参数直接变成类的属性声明。 -
Getter 与 Setter,示例如下:
class Employee{
private _code:string;
get code():string{ return this._code; }
set code(newCode:string){
if(checkCode(newCode){
this._code = newCode;
} else{
console.log("Error:the code is taken")
}
}
}
只有 Getter 没有 Setter 说明对应的属性是 readonly
的。这将用于生成 .d.ts
文件。
-
类可以声明静态变量,示例:
static origin = {x: 0, y: 0};
-
类可以声明为抽象类,如
abstract class Animal
,抽象 类可以声明抽象方法。这一点类似 Java。
参考
网友评论