接口
「这是我参与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)