TypeScript | 青训营笔记

47 阅读3分钟

这是我参与「第五届青训营」笔记创作活动的第4天。

基本语法

基本数据类型

const q:string = 'string'
const w:number = 1
const e:boolean = true
const r:null = null
const t:undefined = undefined

对象类型

// 定义对象
interface IBytedancer = {
    // 只读属性:属性不可在初始化之外赋值
    readonly jobId: number
    name: string
    sex: 'man' | 'woman' |'other'
    age: number
    // 可选属性:该属性可选
    hobby?: string
    // 任意属性:后续属性均以string作key,any类型的子类型为值
    [key: string]:any
}
​
// 报错:无法分配到“jobId”,因为它是只读属性
bytedancer.jobId = 12345
// 成功:任意属性标注下可以添加any属性
bytedancer:plateform = 'data'
// 报错:缺少属性“name”,hobby可省
const bytedancer: IBytedancer = {
    jobId: 89757,
    sex: 'woman',
    age: 18
}

函数类型

// 函数定义
function add(x: number, y: number): number{
    return x+y
}
// 箭头函数
const mult: (x: number, y: number) => number = (x,y) => x*y
// 接口定义函数
interface IMult {
    (x: number, y: number): number
}
const mult: IMult = (x,y) => x*y
  • 函数重载

    根据参数不同类型,返回不同值

    // 只传入一个number类型的参数
    function fn(params: number): void
    // 传入一个string类型和number类型的参数
    function fn(params: string, params2: number): void
    // 传入两个any
    function fn(params: any, params2?: any): void {
        console.log(params)
        console.log(params2)
    }
    fn(123)
    fn('123', 456)
    

数组类型

// 类型+方括号
type IArr1 = number[]
// 泛型
type IArr2 = Array<string | number | Record<string, number>>
// 元组
type IArr3 = [number, number, string, string]
// 接口
interface IArr4 {
    [key: number]: any
}

泛型

  1. 函数

    类似于函数传参,传入什么类型,T就表示什么类型

    function test <T> (arg:T):T{
      console.log(arg);
      return arg;
    }
    test<number>(111);// 返回值是number类型的 111
    test<string | boolean>('hahaha')//返回值是string类型的 hahaha
    test<string | boolean>(true);//返回值是布尔类型的 true
    
  2. 接口

    // 注意,这里写法是定义的方法哦
    interface Search {
      <T,Y>(name:T,age:Y):T
    }
    ​
    let fn:Search = function <T, Y>(name: T, id:Y):T {
      console.log(name, id)
      return name;
    }
    fn('li',11);//编译器会自动识别传入的参数,将传入的参数的类型认为是泛型指定的类型
    
  3. class Animal<T> {
     name:T;
     constructor(name: T){
      this.name = name;
     }
     action<T>(say:T) {
       console.log(say)
     }
    }
    let cat = new Animal('cat');
    cat.action('mimi')
    
  • 泛型约束

    接口约束

    interface Person {
      name:string;
      age:number;
    }
    function student<T extends Person>(arg:T):T {
      return arg;
    }
    student({name:'lili'});//类型 "{ name: string; }" 中缺少属性 "age",但类型 "Person" 中需要该属性
    student({ name: "lili" , age:'11'});//不能将类型“string”分配给类型“number”
    student({ name: "lili" , age:11});
    
  • 泛型工具类型

    • Partial<T>:将属性全部变为可选项
    • Record<K extends keyof any>:将K的所有属性转换为T类型
    • Pick<T,K extends keyof T>:将K的子属性传给T
    • Exclude<T,U>:移除U类型
    • ReturnType<T>获取T的返回类型

类型断言

类型断言(as)可以手动指定一个值的类型

高级类型

联合/交叉类型

  • 联合类型:A|B,联合类型表示一个值是几种类型之一(只需要满足其中一个接口类型定义的属性)
  • 交叉类型:A&B,多种类型叠加到一起成为一种类型,它所有类型的特性(定义时必须包含交叉类型的所有类型)

类型守卫

定义一个函数,返回一个类型谓词,生效范围为子作用域

interface A {
    a: 1,
    a1: 2
}
interface B {
    b: 1,
    b1: 2
}
// 类型守卫
function getIsA(arg: A | B): arg is A {
    // !!可以将表达式转换成逻辑值
    return !!(arg as A).a
}
function log2(arg: A | B) {
    if (getIsA(arg)) {
        console.log(arg.a1)
    } else {
        console.log(arg.b1)
    }
}