一、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] 来描述数组对象。
四、描述函数对象
由于 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把数字映射成字符串,图为应用场景。
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:类型别名。给其他类型取个名字。
interface:声明接口。描述对象的属性。
type 和 interface 的三个区别
- 区别一:interface 只描述对象,type 则描述所有数据。
- 区别二:type 只是别名,interface 则是类型声明。
- 区别三:type 不可重新赋值,interface 自动合并。
对外 API 尽量用 interface,方便扩展,对内 API 尽量用 type,防止代码分散。