1 | interface LabelledValue { |
1 可选属性
接口里的属性不全都是必需的。
有些是只在某些条件下存在,或者根本不存在。
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?
符号。
1
2
3
4interface SquareConfig {
color?: string;
width?: number;
}
2 只读属性
一些对象属性只能在对象刚刚创建的时候修改其值。
你可以在属性名前用 readonly
来指定只读属性:
1
2
3
4interface Point {
readonly x: number;
readonly y: number;
}
TypeScript具有ReadonlyArray<T>
类型,它与Array<T>
相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改
1
2let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
可以用类型断言重写: 1
a = ro as number[];
2.1
readonly
vs const
最简单判断该用readonly
还是const
的方法是看要把它做为变量使用还是做为一个属性。
做为变量使用的话用 const
,若做为属性则使用readonly
。
3 函数类型
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
1
2
3interface SearchFunc {
(source: string, subString: string): boolean;
}1
2
3
4let mySearch: SearchFunc = function(source: string, subString: string) {
let result = source.search(subString);
return result > -1;
}
4 可索引的类型
可索引类型具有一个 索引签名
,它描述了对象索引的类型,还有相应的索引返回值类型。 1
2
3
4
5
6
7
8interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
可以将索引签名设置为只读,这样就防止了给索引赋值: 1
2
3
4
5interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!myArray[2]
,因为索引签名是只读的。
5 类类型
5.1 实现接口
1 | interface ClockInterface { |
接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员。
5.2 类静态部分与实例部分的区别
1 | interface ClockConstructor { |
类实现接口的时候,只检查实例部分,而类里的constructor属于静态部分,所以不检查。不能检查他,但是你又确确实实在接口里写了,就报错了
那我们一定要用类实现接口,要在接口里用构造器签名怎么办?官网再次给出了解答
1 | interface ClockConstructor { |
6 继承接口
和类一样,接口也可以相互继承。
这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
7 混合类型
一个对象可以同时做为函数和对象使用,并带有额外的属性。
1 | interface Counter { |
8 接口继承类
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。
就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。
接口同样会继承到类的private和protected成员。
这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class Button extends Control implements SelectableControl {
select() { }
}
class TextBox extends Control {
select() { }
}
// 错误:“Image”类型缺少“state”属性。
class Image implements SelectableControl {
select() { }
}
class Location {
}