接口可以在面向对象编程中表示行为的抽象,也可以描述对象的形状。 接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。 (接口中不能含有具体的实现逻辑)
接口就是把一些类中共有的属性和方法抽象出来,可以用来约束实现此接口的类
同名的接口可以写多个,类型会自动合并
interface Person {
readonly id: number;
name: string;
[key:string]: any;
}
let p: Person = {
id: 1,
name: 'zhangsan',
age: 10
}
一、对象类型接口
对象接口可以用来描述对象的形状结构。
// 对象接口
interface List {
id: number;
name: string;
}
interface Result {
data: List[]
}
function render(result: Result) {
result.data.forEach((value) => {
console.log(value.id, value.name)
})
}
let result = {
data: [
{
id: 1,
name: 'zhangsan',
sex: '1'
},
{
id: 2,
name: 'lisi'
}
]
}
render(result)
// 如果将result放在render中,就会对多余的数据进行类型检测
1、as 类型断言
render({
data: [
{
id: 1,
name: 'zhangsan',
sex: '1'
},
{
id: 2,
name: 'lisi'
}
]
} as Result)
2、<>类型断言
render(<Result>{
data: [
{
id: 1,
name: 'zhangsan',
sex: '1'
},
{
id: 2,
name: 'lisi'
}
]
})
3、改变接口
interface List {
id: number;
name: string;
[x: string]: any;
}
4、可索引接口
对数组和对象进行约束
interface User {
[index: number]: string;
}
let user: User = {
0: '0',
1: '1'
}
let userArr: User = ['1','2']
interface IVegetables {
readonly color:string,
size:string
}
interface IVegetables{
age?:number,
taste:'sour'|'sweet'
}
const tomato:IVegetables = {
color:'red',
size:'10',
taste:'sour'
}
tomato.color = 'green'; // 仅读属性不能进行修改
?标识的属性为可选属性, readOnly
标识的属性则不能修改。多个同名的接口会自动合并
const tomato:IVegetables = {
color:'red',
size:'10',
taste:'sour',
type:'蔬菜'
} as IVegetables; // 多余的属性可以使用类型断言
二、函数类型接口
1、函数接口参数
const fullName = ({firstName,lastName}:{firstName:string,lastName:string}):string =>{
return firstName + lastName
}
我们可以约束函数中的参数,但是类型无法复用
interface IFullName {
firstName:string,
lastName:string
}
const fullName = ({firstName,lastName}:IFullName):string =>{
return firstName + lastName
}
2、函数类型接口
interface IFullName {
firstName:string,
lastName:string
}
interface IFn {
(obj:IFullName):string
}
const fullName:IFn = ({firstName,lastName})=>{
return firstName + lastName
}
// type定义函数
type Add = (x: number, y: number) => number
let add: Add = (a, b) => a + b
3、函数混合类型
interface Lib {
(): void;
version: string;
doSomething(): void;
}
function getLib() {
let lib: Lib = (() => {}) as Lib;
lib.version = '1.0';
lib.doSomething = () => {};
return lib;
}
// 可以创建多个实例
let lib1 = getLib();
lib1();
// 可以调用实例方法
lib1.doSomething();
三、整理函数类型
1、如何定义函数
1、使用function直接定义(可以通过类型推断出函数返回值类型,所以不用直接定义)
function add1 (x: number, y: number) {
return x + y;
}
2、通过一个变量定义函数类型
let add2: (x: number, y: number) => number
3、通过类型别名定义函数类型
type add3 = (x: number, y: number) => number
4、通过接口定义函数类型
interface add4 {
(x: number, y: number): number
}
注意:后三种只是函数类型的定义,并没有实现。想要实现需要自己书写函数体。
2、函数的参数
3、函数重载
function add8(...rest: number[]): number;
function add8(...rest: string[]): string;
function add8(...rest: any[]): any {
let first = rest[0];
if (typeof first === 'string') {
return rest.join('');
}
if (typeof first === 'number') {
return rest.reduce((pre, cur) => pre + cur)
}
}
console.log(add8(1, 2, 3)) // 6
console.log(add8('a', 'b', 'c')) // abc