05Typescript中的接口的用途以及属性类型接口

接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。 typescrip 中的接口类似于 java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

属性接口

定义方法:

1
2
3
4
function printLabel(): void {
console.log("printLabel");
}
printLabel();

定义方法传入参数:

1
2
3
4
5
function printLabel(label: string): void {
console.log("printLabel");
}

printLabel("hahah");

自定义方法传入参数,对 json 进行约束:

1
2
3
4
5
6
7
8
9
function printLabel(labelInfo: { label: string }): void {
console.log("printLabel");
}

printLabel("hahah"); //错误写法

printLabel({ name: "张三" }); //错误的写法

printLabel({ label: "张三" }); //正确的写法

对批量方法传入参数进行约束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//就是传入对象的约束
interface FullName {
firstName: string; //注意;结束
secondName: string;
}
function printName(name: FullName) {
// 必须传入对象 firstName secondName
console.log(name.firstName + "--" + name.secondName);
}

// printName('1123'); // 报错
printName({
// age: 20, // 报错
firstName: "张",
secondName: "三",
});

// 换一种方式传参:传入对象
var obj = {
/*传入的参数必须包含 firstName secondName*/
age: 20,
firstName: "张",
secondName: "三",
};
printName(obj); //张--三

function printInfo(info: FullName) {
// 必须传入对象 firstName secondName
console.log(info.firstName + info.secondName + info.age);
}
printInfo({
firstName: "李",
secondName: "四",
}); // 李四

可选属性接口:

1
2
3
4
5
6
7
8
9
10
11
interface FullName {
firstName: string; //注意;结束
secondName?: string;
}
function printName(name: FullName) {
console.log(name);
}

printName({
firstName: "张",
}); // {firstName: '张'}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interface Config {
type: string;
url: string;
data?: string;
dataType: string;
}

// 原生js封装ajax
function ajax(config: Config) {
var xhr = new XMLHttpRequest();
xhr.open(config.type, config.url, true);
xhr.send(config.data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log("成功");
if (config.dataType == "json") {
console.log(JSON.parse(xhr.responseText));
} else {
console.log(xhr.responseText);
}
}
};
}
ajax({
type: "get",
data: "name=zhangsan", // 可传可不传
url: "http://a.itying.com/api/productlist", //api
dataType: "json",
});

函数类型接口

接口能够描述 JavaScript 中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 定义接口
interface encrypt {
(key: string, value: string): string;
}

var md5: encrypt = function (label: string, val: string): string {
// 模拟操作
return label + val;
};

console.log(md5("name", "张三")); //name张三

// 批量约束
// 函数的参数名不需要与接口里定义的名字相匹配
var sha1: encrypt = function (label: string, val: string): string {
return label + "---" + val;
};

console.log(sha1("name", "韩梅梅")); //name---韩梅梅

可索引接口

与使用接口描述函数类型差不多,我们也可以描述那些能够“通过索引得到”的类型(数组、对象的约束),比如 a[0]或 ageMap[“name”]。 可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
让我们看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 对数组的约束
interface UserArr {
[index: number]: string;
}

var arr: UserArr = ["aaa", "bbb"];

console.log(arr["0"]); // aaa

// 对对象的约束
interface UserObj {
[index: string]: string;
}

var person: UserObj = { name: "张三" };

console.log(person.name); // 张三

类类型接口

类类型接口是用来明确的强制一个类去符合某种契约,和抽象类抽象有点相似。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface Animal {
name: string;
eat(str: string): void;
}

class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
eat() {
console.log(this.name + "吃骨头");
}
}

var d = new Dog("小黑");

d.eat(); //小黑吃骨头

class Cat implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
eat(food: string) {
console.log(this.name + "吃" + food);
}
}

var e = new Cat("小花");
e.eat("老鼠"); //小花吃老鼠

继承接口

和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Animal {
eat(): void;
}

// 接口继承
interface Person extends Animal {
work(): void;
}

class Web implements Person {
public name: string;
constructor(name: string) {
this.name = name;
}
eat() {
console.log(this.name + "喜欢吃馒头");
}
work() {
console.log(this.name + "写代码");
}
}

var w = new Web("小李");
w.eat(); //小李喜欢吃馒头
w.work(); //小李写代码

下面再看一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
interface Animal {
eat(): void;
}

interface Person extends Animal {
work(): void;
}

class Programmer {
public name: string;
constructor(name: string) {
this.name = name;
}

coding(code: string) {
console.log(this.name + code);
}
}

class Web extends Programmer implements Person {
constructor(name: string) {
super(name);
}
eat() {
console.log(this.name + "喜欢吃馒头");
}
work() {
console.log(this.name + "写代码");
}
}

var w = new Web("小李");
w.coding("写ts代码"); //小李写ts代码