TypeScript接口
接口
在编程中,接口是一种编程规范,它定义了行为和动作规范,接口起到了规范的作用,比如长方形必须要有长和宽,至于是多少不管,但是必须要有,
接口不关心实现的细节是什么。
interface vs type
- interface(接口)和 type(类型别名)的对比:
- 相同点:都可以给对象指定类型
- 不同点:
-
- 接口,只能为对象指定类型
-
- 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
- 推荐:能使用 type 就是用 type
interface IPerson {name: stringage: numbersayHi(): void
}// 为对象类型创建类型别名
type IPerson = {name: stringage: numbersayHi(): void
}// 为联合类型创建类型别名
type NumStr = number | string
属性类型接口
interface User {name: string,age: number,address?:string
}let user1:User = {name: 'zs',age: 15
}let user2:User = {name: 'ls',age: 20,address: '重庆'
}
定义接口,使用interface
关键字定义接口,定义好后,接口内部是属性可以起到约束作用。
函数属性接口
interface User {name: string,age: number
}function show(user: User):User[] {return [user]
}
函数的参数以及返回的数据类型都可以使用interface
接口去定义,起到复用效果。
函数类型接口
接口可以定义一个函数类型,可以对函数的参数以及返回值做约束
interface Login{(account:string,password:number):string
}let login:Login = function(account, password) {return ''
}
可索引接口
对象可索引接口
interface User {name: string,[k: string]: any
}let user:User = {name: 'zs',age: 12
}
[k: string]
:代表对象中的键必须是字符串,其中k
是一个变量,可以随意命名
[k: string]: any
:右侧的any代表对象中属性的值是任意类型。
数组可索引接口
interface numberArray {[i: number]:number
}
let arr1:numberArray=[1,5]interface stringArray {[i: number]:string
}
let arr2:stringArray = ['1','2']export {}
[i: number]
:代表数组的下标必须是数字
[i: number]: number
:右侧的number
代表数组的值必须存放数字
当一个对象类型被多次使用时,一般会使用接口(interface
)来描述对象的类型,达到复用的目的
- 解释:
-
- 使用
interface
关键字来声明接口 - 接口名称(比如,此处的 IPerson),可以是任意合法的变量名称,推荐以
I
开头 - 声明接口后,直接使用接口名称作为变量的类型
- 因为每一行只有一个属性类型,因此,属性类型后没有 ;(分号)
- 使用
interface IPerson {name: stringage: numbersayHi(): void
}let person: IPerson = {name: 'jack',age: 19,sayHi() {}
}
类类型接口
- 类的继承是单继承,不能是多继承
- 接口可以对类进行约束,可以约束类中必须有某些方法。
- 类要实现接口才能达到约束目的
通过implements
实现接口
interface IPsp {playGame(name: string): void
}interface IPhone {call(name: string): void;playGame(name: string): void;
}class Psp implements IPsp {playGame(name: string): void {console.log('正在玩' + name);}
}class Phone implements IPhone {call(name: string): void {console.log('打电话给' + name);}playGame(name: string): void {console.log('正在玩' + name);}}
类可以实现多个接口,使用逗号隔开
interface Paizhao {takePhoto(): void
}interface IPhone {call(name: string): void;playGame(name: string): void;
}class Phone implements IPhone, Paizhao {takePhoto(): void {console.log('正在拍照');}call(name: string): void {console.log('打电话给' + name);}playGame(name: string): void {console.log('正在玩' + name);}
}
接口中定义一个方法有两种方式:
interface IPhone {call(name: string): void;playGame: (name: string) => void
}
接口继承
- 如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承来实现复用
- 比如,这两个接口都有 x、y 两个属性,重复写两次,可以,但很繁琐
interface Point2D { x: number; y: number }
interface Point3D { x: number; y: number; z: number }
- 更好的方式:
interface Point2D { x: number; y: number }
// 继承 Point2D
interface Point3D extends Point2D {z: number
}
- 解释:
-
- 使用
extends
(继承)关键字实现了接口 Point3D 继承 Point2D - 继承后,Point3D 就有了 Point2D 的所有属性和方法(此时,Point3D 同时有 x、y、z 三个属性)
- 使用
与类型别名的区别
- 接口只能用在对象类型中
// 接口类型
interface A {username: string,age: number
}
let a: A = {username: 'zs',age: 12
}// 别名
type B = string;
let b: B = 'hello'
- 接口可以合并
// 接口
interface A {username: string
}
interface A {age: number
}
let a: A = {username: 'zs',age: 12
}// 别名--报错
type A = {username: string
}
type A = {age: number
}
let a: A = {username: 'zs',age: 12
}
- 接口可以继承
//接口
interface A {username: string
}
interface B extends A {age: number
}
let b: B = {username: 'li',age: 16
}// 别名--报错
type A = {username: string
}
type B extends A {age: number
}
let b: B = {username: 'li',age: 16
}
- 类型名别具有映射类型的写法
// 别名
type A = {[P in 'username' | 'age']: string
}// 接口 -- 报错
interface B {[P in 'username' | 'age']: string
}