基本使用
接口的本质作用是: 定义对象的数据结构
// 不使用接口
// 声明函数 (参数使用对象解构)
function getFullname({firstName, lastName}): string {
return `${firstName}-${lastName}`
}
// 使用函数
// 正常使用 --- 编译通过
getFullname({
firstName: 'Klaus',
lastName: 'Wang'
}) // => Klaus-wang
// 非正常使用 --- 编译依旧通过
getFullname({
firstName: 'Klaus',
lastName: 123
}) // => Klaus-123
// 使用接口
// 定义接口
// 1. 接口首字母一般大写
// 2. 为了声明数据类型是一个接口类型,所以可以在命名前加上I, 即IUserInfo
interface UserInfo {
firstName: string,
lastName: string
}
function getFullname({firstName, lastName}: UserInfo):string {
return `${firstName}-${lastName}`
}
getFullname({
firstName: 'Klaus',
lastName: 'Wang'
}) // -> Success
getFullname({
firstName: 'Klaus',
lastName: 123
}) // -> Error
另一种写法
function getFullname({firstName, lastName}: {
firstName: string,
lastName: string
}):string {
return `${firstName}-${lastName}`
}
可选参数
// 可选参数
interface UserInfo {
name: string,
gender?: string // 设置gender是可选参数,可以传递也可以不传递
}
function getUserInfo({ name, gender }: UserInfo) {
return `name = ${name}, gender = ${gender || 'male'}`
}
// 在这里不传递gender
alert(getUserInfo({
name: 'Klaus'
}))
多余属性检测
// 如何绕过多余属性检测的方式
// 什么是多余属性检测
interface UserInfo {
name: string,
gender?: string
}
function getUserInfo({ name, gender }: UserInfo) {
return `name = ${name}, gender = ${gender || 'male'}`
}
// 在调用的时候,多传入了一个没有使用到的属性 age
// ts检测出传入的对象,多了一个属性,所以会报错
// 这就是多余属性检测
alert(getUserInfo({
name: 'Klaus',
gender: 'male',
age: 23
}))
方式1
// 类型断言
interface UserInfo {
name: string,
gender?: string
}
function getUserInfo({ name, gender }: UserInfo) {
return `name = ${name}, gender = ${gender || 'male'}`
}
alert(getUserInfo({
name: 'Klaus',
gender: 'male',
age: 23
} as UserInfo))
方式2
// 索引签名
interface UserInfo {
name: string,
gender?: string,
// 这里是索引签名
// props 是你的参数名称,任意
// string: 表示的是你参数名称必须是一个字符串字符串
// any: 表示你传入的参数的类型任意
// []: 表示个数不唯一,可以是多个
[props: string]: any
}
function getUserInfo({ name, gender }: UserInfo) {
return `name = ${name}, gender = ${gender || 'male'}`
}
alert(getUserInfo({
name: 'Klaus',
gender: 'male',
age: 23
}))
方式3
// 类型兼容性
interface UserInfo {
name: string,
gender?: string
}
function getUserInfo({ name, gender }: UserInfo) {
return `name = ${name}, gender = ${gender || 'male'}`
}
/**
* 类型兼容性原理
* 有a和b 2个对象
*
* 如果 a = b 成立
* 则表示
* b中有的属性,a中都有,且必须都存在
* 但是a中可以有b中没有的属性
*
*
* 例如
* a = {name: 'Klaus'}
* b = {name: 'Steven'}
*
* a = b // -> Success
*
* 例如
* a = {name: 'Klaus', age: 23}
* b = {name: 'Steven'}
*
* a = b // -> Success
*
* 例如
* a = {name: 'Klaus'}
* b = {name: 'Steven', age: 23}
*
* a = b // -> Error
*/
const args = {
name: 'Klaus',
gender: 'male',
age: 23
}
alert(getUserInfo(args))
只读属性
// 只读属性
interface UserInfoInter {
readonly name: string
}
let user: UserInfoInter = {
name: 'Klaus'
}
user.name = 'Steven' // -> Error
定义特殊对象的类型
数组
// 数组 是一种特殊的对象
// 所以可以设置数组的属性是只读的
interface ArrInter {
0: number,
readonly 1: number
}
let arr: ArrInter = [213, 321]
arr[0] = 222 // -> Success
arr[1] = 222 // -> Error
函数
interface addFunc {
(num1: number, num2: number): number
}
const add: addFunc = (num1, num2) => num1 + num2
索引
// 为索引定义类型
// 定义一个对象
// 对象的属性名为字符串
// 对象的属性值也是字符串
interface RoleDic {
[prop: string]: string
}
/**
* 在对象中,所有的属性名全部会自动被转换为字符串字符串
* 也就是说 1 === '1'
* true ==== 'true'
*/
const role: RoleDic = {
name: 'Klaus',
1: 'demo',
true: 'true'
}
接口
接口的作用 是为了提取对象中的公共属性,以便于提升复用性
// 不使用接口
interface PersonnInter {
name: string
}
interface UserInter {
name: string,
age: number
}
interface StudentInter {
name: string,
gender: string
}
// 很明显,这里的name属性,重复出现了3次
// 使用接口 进行定义
// 不使用接口
interface PersonnInter {
name: string
}
interface UserInter extends PersonnInter {
age: number
}
interface StudentInter extends PersonnInter {
gender: string
}
混合类型
即一个定义可以作为2种或者以上类型来进行使用
举个例子: 一个对象可以同时做为函数和对象使用,并带有额外的属性。
// 定义一个计数器,每调用一次 变量加一,并输出变量的值
let count = 0
function add() {
return count ++
}
但是这么做,会导致存在全局变量count,所以会存在污染全局变量
// 方式1 --- IIFE
const add = (() => {
let count = 0
return () => ++count
})()
// 方式2 --- 混合类型
const add = () => {
return ++add.count
}
// 函数是一种特殊的对象
add.count = 0
// ---> 此时add 即是函数,又是对象,所以add就是一种混合类型
// 使用ts进行实现混合类型
interface Counter {
(): void,
count: number
}
// 工厂函数
const getCounter = (): Counter => {
const c = () => ++c.count
c.count = 0
return c
}
const counter: Counter = getCounter()