Skip to content

TS 语法细节

联合类型

  1. 联合类型是由两个或者多个其他类型组成的类型;
  2. 联合类型中的每一个类型被称之为联合成员(union's members);
  3. 我们拿到的值可能是 string 或者 number,我们就不能对其调用 string 上的一些方法;
  4. 我们需要使用 TypeScript 缩小的代码结构,推断出更加具体的类型
  5. 联合类型使用 | 符号
ts
// 1.联合类型的基本使用
let foo: string | number = '123'
foo = 123

// 使用的时候要特别小心
if (typeof foo === 'string') {
	console.log(foo)
}

// 2.案例: 打印id
function printID(id: number | string) {
	console.log('您的ID:', id)

	// 类型缩小
	if (typeof id === 'string') {
		console.log(id.length)
	} else {
		console.log(id)
	}
}

printID(123)
printID('123')

交叉类型

  1. 交叉类似表示需要满足多个类型的条件
  2. 交叉类型使用 & 符号
ts
// 交叉类型: 两种(多种类型)要同时满足
interface ISj {
	name: string
	age: number
}

interface ILike {
	like: string
}

const infos: ISj & ILike = {
	name: '三九',
	age: 19,
	like: '不忘初心,方得始终!',
}
console.log(infos) // { name: '三九', age: 19, like: '不忘初心,方得始终!' }

type 类型别名

ts
// 1.给 ID 取别名
// 赋值的方式
type IDType = number | string

function printID(id: IDType) {
	console.log(id)
}

printID(123)
printID('321')

// 2.打印坐标
type PrintPositionType = {
	x: number
	y: number
	z?: number
}

function printCoordinate(point: PrintPositionType) {
	console.log(point.x, point.y, point.z)
}
printCoordinate({ x: 10, y: 100, z: 1000 }) // 10 100 1000
printCoordinate({ x: 9, y: 99 }) // 9 99 undefined

interface 接口的声明

ts
// 声明的方式
interface PointType {
	x: number
	y: number
	z?: number
}

function printCoordinate(point: PointType) {
	console.log(point.x, point.y, point.z)
}
printCoordinate({ x: 10, y: 100, z: 1000 }) // 10 100 1000
printCoordinate({ x: 9, y: 99 }) // 9 99 undefined

export {}

interface 和 type 区别

如果是非对象类型的定义使用 type,如果是对象类型那么声明使用 interface

区别一:type 类型使用更广泛,接口类型只能用了声明对象

ts
type NumberType = number
type IDType = string | number

区别二:在声明对象时,interface 可以多次声明

ts
interface IPoint {
	x: number
	y: number
}
interface IPoint {
	z?: number
}
const point: IPoint = {
	x: 99,
	y: 20,
	z: 90,
}

区别三: interface 支持继承

ts
interface IPerson {
	name: string
	age: number
}
// 继承上面的 IPerson
interface ISj extends IPerson {
	// name: string
	// age: number
	like: string
}

类型断言 as

ts
// 获取 DOM 元素 <img class='img'/>
const imgEl = document.querySelector('.img') as HTMLImageElement
imgEl.src = 'xxxx'
imgEl.alt = 'yyyy'

非空类型断言 !

非空断言使用的是 ! ,表示可以确定某个标识符是有值的,跳过 ts 在编译阶段对它的检测;

ts
interface Ipreson {
	name: string
	age: number
	like?: {
		name: string
	}
}

const infos: Ipreson = {
	name: 'sj',
	age: 19,
}
// 非空类型断言(有点危险,只有确保有值的情况下才使用)
infos.like!.name = '不忘初心,方得始终!'

字面量类型

ts
// 1.字面量类型的基本使用
const name: 'sj' = 'sj'
let age: 18 = 18

// 2.将多个字面量类型联合起来
type Direction = 'left' | 'right'
const d1: Direction = 'left'

// 3.案例: 封装请求方法
type MethodType = 'get' | 'post'
function request(url: string, method: MethodType) {}
request('https://api.xbin.cn/api', 'get')

// TS细节
const info = {
	url: 'xxx',
	method: 'post',
}
// request(info.url, info.method) // 报错
// 解决方法一:info.method 进行类型断言
request(info.url, info.method as 'post')

// 解决方法二: 直接让info对象类型是一个子面量类型
const info2 = {
	url: 'xxx',
	method: 'post',
} as const
request(info2.url, info2.method)

export {}

类型缩小

什么是类型缩小呢?

  • 类型缩小的英文是 Type Narrowing(也有人翻译成类型收窄);
  • 我们可以通过类似于 typeof padding === "number" 的判断语句,来改变 TypeScript 的执行路径
  • 在给定的执行路径中,我们可以缩小比声明时更小的类型,这个过程称之为 缩小( Narrowing );
  • 而我们编写的 typeof padding === "number 可以称之为 类型保护(type guards)

常见的类型保护有如下几种:

  • typeof
  • 平等缩小(比如===、!==)
  • instanceof
  • in
  • 等等
ts
// 1.typeof 使用最多
type ID = number | string
function printId(id: ID) {
	if (typeof id === 'string') {
		console.log(id.length, id.split(' '))
	} else {
		console.log(id)
	}
}

// 2.方向的类型判断 字面量类型
type Direction = 'left' | 'right'
function switchDirection(direction: Direction) {
	if (direction === 'left') {
		console.log(direction)
	}
}

// 3.传入一个日期打印日期
function printDate(date: string | Date) {
	if (date instanceof Date) {
		console.log(date.getTime())
	} else {
		console.log(date)
	}
}

// 4.判断是否有某个属性
interface ISwim {
	swim: () => void
}
interface IRun {
	run: () => void
}
function move(animal: ISwim | IRun) {
	if ('swim' in animal) {
		animal.swim()
	} else if ('run' in animal) {
		animal.run()
	}
}

const fish: ISwim = {
	swim: function () {},
}
const dog: IRun = {
	run: function () {},
}