TS 语法细节
联合类型
- 联合类型是由两个或者多个其他类型组成的类型;
- 联合类型中的每一个类型被称之为联合成员(union's members);
- 我们拿到的值可能是 string 或者 number,我们就不能对其调用 string 上的一些方法;
- 我们需要使用 TypeScript 缩小的代码结构,推断出更加具体的类型
- 联合类型使用
|
符号
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')
交叉类型
- 交叉类似表示需要满足多个类型的条件
- 交叉类型使用
&
符号
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 () {},
}