TypeScript笔记——类型

130 阅读3分钟

一、ts中有哪些数据类型

JS数据类型:null、undefined、string、number、boolean、bigint、symbol、object(Array、Function、Date ...)
TS数据类型:以上所有,加上 void、never、enum、unknown、any,再加上自定义类型 type、interfacr。

二、描述普通对象

由于 object 不精确,所以 TS 一般使用 索引签名Record泛型 来描述普通对象。

//索引签名
type A = { 
  [k: string]: number
}

// Record 泛型
type A2 = Record<string, number>

type A3 = {
  name: string,
  age: number
}

深入对象语法(描述对象)

1. type 或 interface
type Person = {
  name: string
}
interface Person {
  name: string
}
2. 索引签名 或 映射类型(多用于范型)
type Hash = { //索引签名
  [k: string]: unknown
}

type Hash = { // 映射类型(多用于范型)
  [k in string]: unknown
}
3. 问号表示可选
interface InputProps {
  defaultValue ?: string
  value ?: boolean
  onChange ?: () => void
}
4. readonly 表示只读

readonly 表示只读,不可写。但是可以修改数组。

interface User {
  readonly id: number
  readonly name: string
  readonly scores: number[]
}
const u: User = {
  id:1,
  name: 'Bumble',
  scores: [99, 100]
}
u.scores[0] = 98 // 不报错

三、描述数组对象

由于 array 不精确,所以 TS 一般使用 Array<?>[string,number] 来描述数组对象。

image.png

四、描述函数对象

由于 Function 不精确,所以 TS 一般使用 () => ? 来描述函数对象。

type FnA = (a: number, b:number) => number
const a : FnA = (x:number) => {
  return 123
}
a(1,2)

以下是支持 this 的函数例子

type Person = {name: string, age: number, sayHi: FnWidthThis}

type FnWidthThis = (this: Person, name:string) => void

const sayHi: FnWidthThis = function (){
  console.log('hi' + this.name)
}


const x: Person = {name:'Bumble', age: 20, sayHi: sayHi}

x.sayHi('Jack') //调用时需要传this, 方法一
sayHi.call(x, 'Jack') //方法二

五、描述其他对象

其他对象一般直接用 class 描述

const d: Date = new Date()

const r: RegExp = /ab+c/
const r2: RegExp = new RegExp('ab+c')

const m: Map<string, number> = new Map()
m.set("xxx", 2)

const wm: WeakMap<{name: string}, number> = new WeakMap()

const s: Set<{name:string}> = new Set()
s.add({name: 'Bumble'})

const ws: WeakSet<string[]> = new WeakSet()

六、用TS描述 bigint 和 symbol

const n: bigint = 100n
const s: symbol = Symbol("s")

七、any 和 unknown

any :支持所有类型,相当于全集。TS绝大部分规则对any不生效。
unknown : 不知道它的类型。一般使用 unknown 而不是 any,因为有机会进行类型断言

const a: unknown = 1;
(a as string).split(',')  //类型断言

八、never

never相当于空集,用于做检查。

九、enum 枚举

什么时候使用 enum ?
当要做一个映射的时候使用enum,例如把数字映射成字符串(一般只在这个情况下使用enum)、把字符串映射成字符串。

举例一: 使用enum把数字映射成字符串,图为应用场景。

image.png

enum A{
  todo = 0,
  done, // 不手动赋值时,会自动从上往下递增赋值
  archived,
  deleted
}
let status: A = A.todo // 类型擦除时,A.todo会变为 0
举例二:权限控制
enum Permission { //用二进制位表示权限
  None = 0, // 0000
  Read = 1 << 0,   // 0010
  Write = 1 << 1,  // 0100
  Delete = 1 << 2, // 0100
  Manage = Read | Write | Delete, // 0111
}
type User = {
  permission: Permission
}
const user: User = {
  permission: 0b0101
}
// 若 a&b === b, 则 a 有 b 的所有 1。
if ((user.permission & Permission.Write) === Permission.Write){
  console.log('拥有写权限')
}
if ((user.permission & Permission.Manage) === Permission.Manage){
  console.log('拥有管理权限')
}

十、type 和 interface

type:类型别名。给其他类型取个名字。

image.png

interface:声明接口。描述对象的属性。

image.png

type 和 interface 的三个区别

  1. 区别一:interface 只描述对象,type 则描述所有数据

image.png

  1. 区别二:type 只是别名,interface 则是类型声明。
  2. 区别三:type 不可重新赋值,interface 自动合并。
    对外 API 尽量用 interface,方便扩展,对内 API 尽量用 type,防止代码分散。

image.png