Files
vue3-tutorial/docs/chapter2/2_interface.md
zxfjd3g 832b961d34 doc
2020-11-12 21:07:26 +08:00

187 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2. 接口
TypeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口Interfaces来定义对象的类型。`接口是对象的状态(属性)和行为(方法)的抽象(描述)`
## 接口初探
需求: 创建人的对象, 需要对人的属性进行一定的约束
```
id是number类型, 必须有, 只读的
name是string类型, 必须有
age是number类型, 必须有
sex是string类型, 可以没有
```
下面通过一个简单示例来观察接口是如何工作的:
```typescript
/*
在 TypeScript 中我们使用接口Interfaces来定义对象的类型
接口: 是对象的状态(属性)和行为(方法)的抽象(描述)
接口类型的对象
多了或者少了属性是不允许的
可选属性: ?
只读属性: readonly
*/
/*
需求: 创建人的对象, 需要对人的属性进行一定的约束
id是number类型, 必须有, 只读的
name是string类型, 必须有
age是number类型, 必须有
sex是string类型, 可以没有
*/
// 定义人的接口
interface IPerson {
id: number
name: string
age: number
sex: string
}
const person1: IPerson = {
id: 1,
name: 'tom',
age: 20,
sex: '男'
}
```
类型检查器会查看对象内部的属性是否与IPerson接口描述一致, 如果不一致就会提示类型错误。
## 可选属性
接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。
```typescript
interface IPerson {
id: number
name: string
age: number
sex?: string
}
```
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 `?` 符号。
可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误。
```typescript
const person2: IPerson = {
id: 1,
name: 'tom',
age: 20,
// sex: '男' // 可以没有
}
```
## 只读属性
一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 `readonly` 来指定只读属性:
```typescript
interface IPerson {
readonly id: number
name: string
age: number
sex?: string
}
```
一旦赋值后再也不能被改变了。
```typescript
const person2: IPerson = {
id: 2,
name: 'tom',
age: 20,
// sex: '男' // 可以没有
// xxx: 12 // error 没有在接口中定义, 不能有
}
person2.id = 2 // error
```
### readonly vs const
最简单判断该用 `readonly` 还是 `const` 的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 `const`,若做为属性则使用 `readonly`
## 函数类型
接口能够描述 JavaScript 中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
```typescript
/*
接口可以描述函数类型(参数的类型与返回的类型)
*/
interface SearchFunc {
(source: string, subString: string): boolean
}
```
这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。 下例展示了如何创建一个函数类型的变量,并将一个同类型的函数赋值给这个变量。
```typescript
const mySearch: SearchFunc = function (source: string, sub: string): boolean {
return source.search(sub) > -1
}
console.log(mySearch('abcd', 'bc'))
```
## 类类型
### 类实现接口
与 C# 或 Java 里接口的基本作用一样TypeScript 也能够用它来明确的强制一个类去符合某种契约。
```typescript
/*
类类型: 实现接口
1. 一个类可以实现多个接口
2. 一个接口可以继承多个接口
*/
interface Alarm {
alert(): any;
}
interface Light {
lightOn(): void;
lightOff(): void;
}
class Car implements Alarm {
alert() {
console.log('Car alert');
}
}
```
## 一个类可以实现多个接口
```typescript
class Car2 implements Alarm, Light {
alert() {
console.log('Car alert');
}
lightOn() {
console.log('Car light on');
}
lightOff() {
console.log('Car light off');
}
}
```
## 接口继承接口
和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
```typescript
interface LightableAlarm extends Alarm, Light {
}
```