TypeScript——04——ts中的接口(Interface)

1、前言

TS新增了一个重要概念:接口,分为对象类型接口和函数类型接口
接口能够约束对象,函数,类的结构和类型,是一种代码协做必须遵照的契约

接口的定义方式:后端

使用interface关键字

2、对象类型接口

接口中可定义 肯定属性、可选属性、任意属性、只读属性数组

一、肯定属性
复制代码
interface UserInfo {
  name: string;
  age: number;
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20
};
复制代码

接口中约束好的肯定属性,定义对象变量的时候 不能少也 不能多函数

二、可选属性spa

复制代码
interface UserInfo {
  name: string;
  age: number;
  sex?:string 
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20
};
复制代码

接口中的可选属性,是表示在对象变量中能够不存在code

三、任意属性对象

复制代码
interface UserInfo {
  name: string;
  age: number;
  sex?:string ;
  [propName: string]:any;
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20,
  test1: 'lala',
  test2: 'ff',
  test3:123
};
复制代码

注:一旦定义了任意属性,那么肯定属性和可选属性的类型都必须是任意属性类型的子类;blog

定义了任意属性后,对象变量中的属性个数才能够出现比接口的属性数量多的状况索引

四、只读属性接口

复制代码
interface UserInfo {
  readonly id: number;
  name: string;
  age: number;
  sex?: string;
  [propName: string]: any;
}

const myInfo: UserInfo = {
  id: 1,
  name: "haha",
  age: 20,
  test1: "lala",
  test2: "ff",
  test3: 123
};
复制代码

只读属性也是肯定属性,在对象变量定义的时候必须有值,此后不能修改ip

对象接口示例

以查询商品列表接口API为例:

// 接口声明:API协议约定返回格式
interface ResponseData {
    resCode: number;
    resData: ResultData[];
    message: string;
}

// 数据接口声明
interface ResultData {
    productId: number;
    productName: string;
}

符合接口约定的对象:

let resultData = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt实战" },
        { productId: 2, productName:"TypeScipt从入门到精通" },
    ],
    message: "success"
}

输出函数对结果进行打印:

function render(res: ResponseData) {
    console.log(res.resCode, res.message)
    res.resData.forEach((obj) => {
        console.log(obj.productId, obj.productName)
    })
}

render(resultData);

输出:

0 "success"
1 "TypeScipt实战"
2 "TypeScipt从入门到精通"

额外属性

在接口的实际调用中,后端也常常会传递约定以外的字段,好比:

let resultData = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt实战", remark:""}, // 接口约定之外的remark字段
        { productId: 2, productName:"TypeScipt从入门到精通" },
    ],
    message: "success"
}

此时,并无报错,TS容许这种状况的发生

只要传入的对象知足接口的必要条件就能够被容许,即便传入多余的字段也能够经过类型检查

但也有例外,若是直接传入对象字面量,TS就会对额外的字段进行类型检查

如下方式会报错:

render({
    resCode: 0, resData: [ { productId: 1, productName:"TypeScipt实战", remark: "备注"}, { productId: 2, productName:"TypeScipt从入门到精通" }, ], message: "success" })

 

绕过检查的方法有3种:

1,将对象字面量赋值给一个变量

将对象字面量赋值给一个变量后,在render再也不报错:

let result = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt实战", remark: "备注"},
        { productId: 2, productName:"TypeScipt从入门到精通" },
    ],
    message: "success"
}
render(result)
2,使用类型断言
使用类型断言方式,明确告诉编译器类型是什么,编译器就会绕过类型检查

方法1:

object as targetInterface
render({
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt实战", remark:""},
        { productId: 2, productName:"TypeScipt从入门到精通" },
    ],
    message: "success"
} as ResponseData)

方法二:

<targetInterface>object
render(<ResponseData>{
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt实战", remark: "备注"},
        { productId: 2, productName:"TypeScipt从入门到精通" },
    ],
    message: "success"
})
3,使用字符串索引签名

添加字符串索引签名:

interface ResultData {
    productId: number;
    productName: string;
    [remark: string]: any;  // 字符串索引签名
}
表示用任意字符串去索引List,可获得任意结果,此时List能够实现支持多个属性

3、函数接口

函数定义方式

1,在TS中,可使用一个变量直接定义函数:

// 1,使用变量定义函数
let add: (x: number, y: number) => number
= (x, y){
  return x+y;
};
add(1,2)

 

2,还可使用接口来定义函数:

// 2,使用接口定义函数
interface Add {
    (x: number, y: number): number
}
let myFunc: Add = function(x, y){
  return x+y;
};
myFunc(1,2);

 

3,使用类型别名来定义函数:

类型别名使用type关键字,至关于为函数类型起一个名字
// 3,使用类型别名来定义函数
type Add = (x: number, y: number) => number

 

4、可索引类型的接口

当不能肯定接口中有多少个属性时,可使用可索引类型接口
可索引类型接口能够用数字去索引,也能够用字符串去索引
1,数字索引接口:

声明一个数字索引类型的接口:

表示用任意数字去索引numberIndex都会获得一个string
interface numberIndex {
    [x: number]: string
}
// 至关于声明了一个字符串类型的数组
let chars: numberIndex = ['A', 'B']
2,字符串索引接口:

声明一个字符串索引类型的接口:

表示用任意的字符串去索引stringIndex获得的结果都是string
interface stringIndex {
    [x: string]: string
}

这样声明后,就不能声明number类型的成员了,会报错

interface stringIndex {
    [x: string]: string
    y: number;// Property 'y' of type 'number' is not assignable to string index type 'string'.
}
3,两种索引签名混用:
在上边的字符串索引接口stringIndex中,添加数字索引签名
interface stringIndex {
    [x: string]: string
    [z: number]: string
}
这样作.接口既能够用数字索引Names也能够用字符串索引Names

但须要注意:数字索引的返回值,必定要是字符串返回类型的子类型

这是由于JS会进行类型转换,将number转换成string,这样就能保证类型的兼容性

好比:将数组索引的返回值改为number:

interface stringIndex {
    [x: string]: string
    [z: number]: number    // // Numeric index type 'number' is not assignable to string index type 'string'.
}

这样就和String类型不兼容了,要取一个可以兼容number的类型,好比any:

interface stringIndex {
    [x: string]: any
    [z: number]: number // Numeric index type 'number' is not assignable to string index type 'string'.
}
相关文章
相关标签/搜索