今天继续学 @小满zs 的 TS 课程,在这里记录一下。
一、接口
在 typescript 中,我们定义对象的方式要用关键字 interface(接口),满子的理解是使用 interface 来定义一种约束,让数据的结构满足约束的格式。定义方式如下:
interface Person {
name: string
age: number
}
const obj = {
name: '鱼钓猫',
age: 18
}
1.1 重名合并
interface Person {
name: string
age: number
}
interface Person {
sex: string
}
-------------------- 上下等价
interface Person {
name: string
age: number
sex: string
}
1.2 继承
interface A extends B {
name: string
age: number
}
interface B {
sex: string
}
----------------------- 上下等价
interface A {
name: string
age: number
sex: string
}
1.3 可选、只读
interface A {
name: string
age?: number // 可有可无
readonly id: number // 可读不可写
readonly cb: () => string // 可读不可写
}
let obj = {
name: "鱼钓猫",
id: 123,
cb: () => "小鱼干"
}
1.4 任意属性 [propName: string]
定义后台返回数据可以使用。propName 可以自定义,通常的值类型为 any。
注:一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集。
interface A {
name: string
age: number
[propName: string]: any
}
let obj: A = {
name: "鱼钓猫",
age: 18,
posi: "我是大哥",
xmzs: "小满最骚"
}
1.5 函数定义
interface Fn {
(name: string, asge: number): number[]
}
const fn: Fn = (name: string, age: number) => {
return [1, 2]
}
二、类型定义
2.1 数组类型
- 基本数组
let arr1: number[] = [1, 2, 3]
let arr2: Array<string> = ["1", "2"] // 泛型
- 对象数组:使用 interface 定义
interface P {
name: string
}
let arr3: P[] = [{ name: "鱼钓猫" }, { name: "小鱼干" }]
- 多维数组
let arr4: number[][] = [[1, 2], []]
let arr5: Array<Array<number>> = [[1, 2], []]
let arr6: number[][][] = [[[1]], []]
- 大杂烩数组
let arr7: any[] = [1, '鱼钓猫', false, {}]
// 指定元祖 需要一一对应
let arr8: [number, string, boolean, {}] = [1, '鱼钓猫', false, {}]
- 函数参数
function fun(...arg: string[]) {
// 剩余参数 就是一个 数组
console.log(arg);
console.log(arguments); // 伪数组
// 内置对象IArguments 专门定义伪数组
let argu: IArguments = arguments
}
// IArguments 原理
interface Arg {
callee: Function
length: number
[idnex: number]: any
}
2.2 函数类型
- 基本参数定义
可选参数和默认值不能同时定义。
function fn1(a: number = 10, b?: number): number {
return a + b; // echo NaN 严格模式下会报错
}
interface User {
name: string
age: number
}
const fn2 = (user: User): User => {
return user
};
- this 定义
ts 可以定义 this 的类型,在 js 中无法使用。
必须是第一个参数定义 this 的类型。
2023年7月,不用定义 this 可以直接使用
interface Obj {
ary: number[]
add: (this: Obj, num: number) => void
}
let obj = {
ary: [1, 2, 3],
add(this: Obj, num: number) {
this.ary.push(num)
}
}
obj.add(4)
console.log('obj',obj) // echo obj { ary: [ 1, 2, 3, 4 ], add: [Function: add] }
- 函数重载
// 函数重载声明
function add(x: string, y: string): string
function add(x: number, y: number): number
// 函数声明
function add(x: string | number, y: string | number): string | number {
if (typeof x == 'string' && typeof y == 'string') {
return x + y
} else if (typeof x == 'number' && typeof y == 'number') {
return x + y
}
}
console.log(add('abc', 'de')); // echo abcde
console.log(add(10, 20)); // echo 30
console.log(add('abc', 20)); // error 没有与此调用匹配的重载。
console.log(add(10, 'abc')); // error 没有与此调用匹配的重载。
- 联合类型
function fn3(val: number | boolean): boolean {
return !!val // 强转 0 => false true => true
}
- 交叉类型:类似接口继承
interface X {
name: string
}
interface Y {
age: number
}
function fn4(data: X & Y): void {
console.log('data', data)
}
fn4({ name: "鱼钓猫", age: 18 })
- 类型断言:只是去除报错,结果该错还错,慎用
function fn5(val: string | number): number {
// 两种断言方式都可 需要加括号
return (val as string).length
return (<string>val).length
}
fn5('12345') // echo 5
fn5(12345) // echo undefined
2.3 内置对象
- ECMAScript 的内置对象:Boolean、Number、String、Date、RegExp、Error
let bool: Boolean = new Boolean()
let num: Number = new Number(true)
let str: String = new String()
let date: Date = new Date()
let reg: RegExp = new RegExp(/ydm/ig)
let err: Error = new Error()
let xhr: XMLHttpRequest = new XMLHttpRequest()
- Dom 和 BOM 的内置对象:HTML(选择器名称)Element 、HTMLElement 、Element、NodeList 、NodeListOf<>
// HTML(选择器名称)Element
let div: HTMLDivElement | null = document.querySelector('div');
let canvas: HTMLCanvasElement | null = document.querySelector('cancas');
// HTMLElement
let html: HTMLElement | null = document.querySelector('header')
// NodeList
let node: NodeList = document.querySelectorAll('div')
// NodeListOf<>
let nodeList: NodeListOf<HTMLDivElement | HTMLElement> = document.querySelectorAll('div')
- 浏览器内置对象:Storage、Location、Promise<>
let storage: Storage = localStorage
let loca: Location = location
let promise: Promise<number> = new Promise((resolve) => 123)
let cookie: string = document.cookie