前端实习准备 — TS大总结

85 阅读4分钟

TS类型

1. 所有JS类型:string number boolean bigInt Symbol undefined null object(数组 对象 函数 日期)
2. any unknown never
3. void enum
4. type interface

变量声明(类型注解)

var/let/const 变量:数据类型 = 值
const name:string = 'muggle'
const name = 'muggle' // 根据赋值类型推导
const name // 无赋值推导为any

基础类型

const a:string = 'muggle'
const b:number = 23
const c:boolean = false
const d:null = null  // 既是值,也是类型
const e:undefined = undefined  // 既是值,也是类型
const f:bigInt = 23n
const g = symbol() // unique symbol
let h = symbol() // symbol

数组和元组

const arr:number[] = [1,2,3]  //类型[]
const arr:Array<number> = [1,2,3]  //Array<类型>
const arr:(number|string)[]=['muggle',23] //(类型1 | 类型2)[]
const arr:[number,string]=[23,'muggle']  //[类型1,类型2]

对象类型

const obj:object = { // 不能修改任何属性和值
    name:'muggle',
    age:23
}
const obj:{name:string,age?:number} = {  // ?为可选
    name:'muggle',
}

函数类型

// 函数声明类型:分别声明参数和返回值类型
function fn(n:number):number{
    return n
}
// 函数变量类型:使用箭头函数
const fn:(n:number)=>number = function(n){
    return n
}
const fn:(n:number)=>number = (n)=>{
    return n
}
// 箭头函数独有类型
const fn = (n:number):number =>{
    return n 
}

// type定义函数类型
type fnType = (n:number) => number
const fn:fnType = (n)=>{
    return n
}
// interface定义函数类型
interface fnType{
    name:string
    (n:number):number // 可添加函数属性
}
const fn:fnType = (n)=>{
    return n
}
fn.name='muggle'
// 构造函数类型
interface newFn {
    new (name:string):void
}
function person(student:newFn){
    const stu = new Student('muggle')
}
class student{
    name:string
    constructor(name:string){
        this.name = name
    }
}
person(student)
// 使用typeof获取函数类型
type fn2 = typeof fn

// 基本使用
class Person{
    name:string
    age:number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    eat(){}
}
const p = new Person('muggle',23)
// extends
class Student extends Person{
    school:string
    constructor(name:string,age:number,school:string){
        super(name,age)
        this.school =  school
    }
    eat(){} // 重写
    study(){}
}

any、unknown、never

any--任何类型,任何操作都合法
unknown--未知类型,不可以赋值给其他变量(除了自身和any)。是所有类型的父类型,可以被任何变量赋值,但需要先类型检查确定变量类型之后才能执行某些类型的独有的操作。一般用于不确定数据类型时。
never--永远不存在值的类型,一般用于封装工具库。

枚举类型enum

将变量可能出现的值列出来,定义在一个类型中,这个类型就是枚举。如果将某个变量声明为枚举类型,则其值就只能是枚举里面列出来的。
enum Direction{
    LEFT = 'left',
    RIGHT = 'right',
    TOP = 'top',
    BOTTOM = 'bottom'
}
type Direction = 'LEFT' | 'RIGHT'  | 'TOP' | 'BOTTOM'

function turn(direction:Direction){
    switch(direaction){
        case Direction.LEFT:
            console.log('left')
            break
        ...
        default:
            break
    }
}

interface和type

1. interface是接口(创建新类型),type是类型别名
2. interface描述对象,type可描述所有类型
3. interface使用extends实现继承,type使用&实现交叉类型
4. interface可重复声明+扩展,type不能

interface person{ // 定义
    name:string,
    age:number
}
interface student extends person{  // 继承
    school:string
}
interface student{  // 重复声明+自动扩展
    addr:string
    eat:()=>void
}

type person = {  // 定义
    name:string
    age:number
}
type student = person & {  // 交叉类型
    school:string
}
// 不能重复声明+无自身扩展

索引签名(键值类型)

interface Entries {
    [key:number]:string
}
type Entries = Record<number,string>

const person:Entries{
    1:'muggle',
    2:'wizar'
}

联合类型和交叉类型 | &

type myType = number | string
type myType = number & string // never
// 交叉类型一般用于对象类型
type one = {
    name:string,
    age:number
}
type two = {
    school:string,
    addr:string
}
type myType = one & two

类型断言 as ! as const

TS无法获取具体的类型信息,我们可以自己断言
const name = 'muggle'
const person = name as string // 断言name是string
const person = <string>name // jsx不可用 
          
// 非空断言,即确定参数有值,需要跳过TS检查
function fn(name?:string){
    console.log(name!.length)       
}
      
// 常量断言,将类型收窄到字面量,即readonly
const arr = ['muggle',23] as const

字面量类型

定义类型为字符串,后续赋值也只能是该字符串
const name:'muggle' = 'muggle'
// 枚举类型就是多个字面量类型联合
type myType = 'left' | 'right'

类型收窄

function person (id:string|number){
    if(typeof id === 'string'){}  // typeof
    if(id instanceof string){}  // instanceof
}
type one = {
    name:string
}
type two = {
    age:number
}
function person(student:one|two){
    if('name' in student){}  // in
}

类型兼容

Type A = Type B,则A可以兼容B,A是B的父类型,A的类型限制没有B严格
// 简单类型兼容
type id = string | number
const name:id = 'muggle'
// 普通对象兼容
interface Person{
    name:string
    age:number
}
const p:Person = {
    name:'muggle',
    age:23,
    id:1
}

泛型

// function
function fn<T1,T2>(name:T1,age:T2):T1{
    return arg
}
fn<string,number>('muggle',23) // 传入特定T
fn('muggle',23) // 根据传入值,类型推导出T

// type
type myType<T> = T | null
const name:myType<string> = 'muggle'

// interface
interface person<T>{
    name:T,
    friends:T[]
}
const p:person = {
    name:'muggle',
    friends:['wizer','other']
}
interface person<T = string>{}//默认值

// class
class person<T>{
    name:T
    firends:T[]
    constructor(name:T,friends:T[]){
        this.name = name
        this.friends =friends
    }
}
const p = new person<string>('muggle',['wizar','other'])