该系列基于typescript中文文档官网重新学习编写的demo,部分描述未必正确,又或者说对到typescript
中不一定正确,仅做学习记录,该系列源于ts4.9.5版本进行试验,与官网相比是不会一直重复串知识点,方便聚焦知识点的实现
可选属性
interface squareConfig {
long: number,
width: number,
height?: number // 可选属性,这个接口的写法叫 option bags
}
function computedSize(config: squareConfig): string {
if (config.height) return config.long * config.width * config.height + '立方'
return config.long * config.width + '平方'
}
const size = computedSize( width: 4, weight: 4, height: 8 })
console.log(size)
只读属性
interface personInfo {
readonly name: string,
readonly age: number,
weight: number
}
const people: personInfo = {
name: 'zf',
age: 18,
weight: 80
}
// people.name = 'aa' // 只读属性不允许赋值
people.weight = 120
额外的属性检查
下列例子中,接口里定义的是color
,然而在传参的时候写的是colour
,color
是可选的并不会报错,但是colour
作为额外属性被识别出来
interface SquareConfig {
color?: string
width?: number
}
type squareRes = { color: string, area: number }
function createSquare(config: SquareConfig): squareRes {
return { color: config.color!, area: config.width! }
}
let mySquare = createSquare({colour: 'blue', width: 10}) // 报错,因为有额外属性
解决方式一: 使用索引签名
interface SquareConfig {
color?: string
width?: number,
[otherParams: string]: any
}
解决方式二: 使用类型断言
- 尖括号语法:
let mySquare = createSquare(<SquareConfig>{colour: 'red', width: 20})
- as 语法:
let mySquare = createSquare({colour: 'red', width: 20} as SquareConfig)
函数类型
入参类型限制,只会将入参逐个与对应类型进行比较,不关心命名是否一致
interface searchFun {
(url: string, method: string, status: number): // 定义入参对应类型
{ reqStr: string, code: number } // 返回限制
}
let requestFun: searchFun
requestFun = function (src, method, code) { // src => url, code => status
const reqStr = `【${method}】 ${src}`
if (code === 200) return { reqStr, code }
return {reqStr: 'request false', code}
}
requestFun('/api/userList', 'get', 200) // { reqStr: '【get】 /api/userList', code: 200 }
可索引的类型
只能接收string
、number
、symbol
或模板文本类型
TypeScript支持两种索引签名:字符串和数字,但数字索引的返回值必须是字符串索引返回值类型的子类型
字符串索引签名能够很好的描述字典模式,确保所有属性与其返回值类型相匹配
interface membersName {
[index: number]: string
}
const members: membersName = ['Bob', 'Joy']
console.log(members[0]) // 'Bob'
interface dictNumberINT {
dictNumber: number,
[field: string]: number
}
const studentNum:dictNumberINT = {dictNumber: 1008688, successCode: 200, failCode: 500}
console.log(studentNum['successCode']) // 200
将数组设置为只读,等价做法
interface ReadonlyStringArray {
readonly [index: number]: string
}
let readonlyArray: ReadonlyStringArray = ['Alice', 'Bob']
// readonlyArray[0] = 'Joy' // 不允许修改只读属性
let readonlyArray2: ReadonlyArray<string> = ['Alice', 'Bob']
// readonlyArray2[0] = 'Joy' // 不允许修改只读属性
继承接口
interface Shape {
color: string
}
interface Square extends Shape {
sideLength: number
}
let square = <Square>{} // 例子这个做法不推荐,导致使用的时候不会提示有可能为undefined,真有这种情况应该使用可选属性,方便他人阅读
console.log(square.color + square.sideLength) // 不会有任何错误提示
square.color = "blue"
square.sideLength = 10
基本用不上的定义
以下即使在阅读文档时你也很难理解其做法是为了面对什么场景,或者压根接触不到,仅做记录
实现接口
一般用不到,class
本身就可以约束了,还特地写多一个interface
来约束class
类class
需要通过关键字implements
来继承接口,接口描述了类的公共部分,而不是公共和私有两部分
interface ClockInterface {
currentTime: string
setTime(d: Date): void
}
class Clock implements ClockInterface {
currentTime: string
setTime(d: Date) {
this.currentTime = d.toLocaleDateString()
}
constructor(timestampe: number) {
this.currentTime = new Date(timestampe).toLocaleDateString()
}
}
let timestampe = 1676255030603
const clock = new Clock(timestampe)
console.log(clock.currentTime)
混合类型
在使用JavaScript第三方库的时候,你可能需要像上面那样去完整地定义类型,反之也就是说,正常开发你也用不到
如果单看这个例子,那就是为了造例子而硬造,不知道究竟能用在什么场景上
interface Counter {
(list: number[]): number,
interval: number,
reset(): void
}
function getCounter(): Counter {
let counter = <Counter>function(list: number[]) {
return list.reduce((pre, next) => pre + next, 0)
}
// 是的,很奇葩,在number上设置属性,但也不会报错
counter.interval = 10
counter.reset = () => {}
return counter
}
还有两个不写了,一个是类静态部分与实例部分的区别,另一个是接口继承类
网友评论