TS --- 接口

197 阅读3分钟

接口

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

TypeScript是一个功能就是为JavaScript提供了静态的类型检测

为此TypeScript为了方便我们对对象的解构进行定义.提出了接口

在约定中,接口的命名一般使用I+大驼峰命名法大驼峰命名法

基本使用

interface IName {
  // 接口中的属性之间 可以使用逗号,封号进行分割多个属性
  // 但是推荐 以直接换行 来分割多个属性
  firstName: string
  lastName: string
}

function getFullName({
  firstName,
  lastName
 }: IName) {
   return `${firstName} ${lastName}`
 }

可选属性

在属性冒号前加上?表示对应的属性是可选的

interface IType {
  // 属性:前加上? 表示该属性是一个可选属性
  color?: string
  type: string
}

function getType({ color, type }: IType) {
  return `A ${ color ? color : '' } ${type}`
}

只读属性

在属性名前面加上readonly,表示该属性是只读的,除初始赋值外 对应的属性值不可以被修改

interface IUser {
  readonly name: string
  readonly age: number
}

/*
	// 如果此时直接定义 不赋值的时候
	// user中的name属性和age属性会被默认设置为undefined,且不可被修改
	let user: User
*/

const user: IUser = {
  name: 'Klaus',
  age: 23
}

// user.name = 'Alex' // error

定义其它类型

在JavaScript中,数组和函数可以被认为是特殊的对象

因此在TypeScript中,我们也可以使用接口来定义数组或函数的结构

使用接口定义数组结构

// 普通数组 --- 类似于 Array<T>
interface IArr<T> {
  [index: number]: T
}

// 只读数组
interface IReadonlyArr<T> {
  readonly [id: number]: T
}

使用接口定义函数结构

interface ISum {
  (num1: number, num2: number): number
}

// 当然一般定义函数结构 还是推荐使用类型别名
type Sum = (num1: number, num2: number) => number

// 在实际调用的时候,对于参数,只要对应位置上的类型一致就可以,并不需要保证对应位置上的参数名保持一致
const sum: ISum = (n1: number, n2: numnber) => n1 + n2

索引签名

所谓索引签名 本质上就是定义索引所对应的数据类型

// 一个 key必须为字符串 value可以为任意类型的 对象
interface IFoo {
  [prop: string]: any
}

const foo: IFoo = {
  name: 'Klaus',
  // 注意: key的类型是数值的时候. 对应的类型是兼容的
  // 因为 在对象实际按照key值去取对应的值的时候
  // 数值类型的key会被转换为字符串类型的key
  18: '18'
}

继承

和类一样,接口也可以通过继承的方式来提升接口和接口之间的可复用性

interface Person {
  name: string
  age: number
}

interface Student extends Person {
  sno: number
}

const stu: Student = {
  name: 'klaus',
  age: 23,
  sno: 1810166
}

多余属性检测

interface IType {
  color?: string
  type: string
}

function getType({ color, type }: IType) {
  return `A ${ color ? color : '' } ${type}`
}

// error --- 多余属性 weight
// 在直接传递对象字面量的时候 要求除可选属性外
// 其余的必传属性必须传递 且对应类型正确
// 同时不可以存在多余的属性
getType({
  color: 'red',
  type: 'tomato',
  weight: '200g'
})

解决方法1 --- 类型断言

interface IType {
  color?: string
  type: string
}

function getType({ color, type }: IType) {
  return `A ${ color ? color : '' } ${type}`
}

getType({
  color: 'red',
  type: 'tomato',
  weight: '200g'
} as IType)

解决方法2 --- 索引签名

interface IType {
  color?: string
  type: string
  [prop: string]: any
}

function getType({ color, type }: IType) {
  return `A ${ color ? color : '' } ${type}`
}

getType({
  color: 'red',
  type: 'tomato',
  weight: '200g'
})

解决方法3 --- 类型兼容性

interface IType {
  color?: string
  type: string
}

function getType({ color, type }: IType) {
  return `A ${ color ? color : '' } ${type}`
}

const desc = {
  color: 'red',
  type: 'tomato',
  weight: '200g'
}

// 这里可以成功赋值的原因 是因为类型兼容性
// a = b --- 类型b 赋值给 类型a 的时候
// 要求 类型a中存在的 类型b中也必须存在
// 类型b中可以存在类型a中不存在的多余属性
// TypeScript会自动通过类型擦除 将这些多余属性去除掉
getType(desc)