浅析TypeScript|青训营笔记

67 阅读4分钟

笔记内容:

  • 为什么要学TS
  • TS基础
  • TS进阶
  • 实战&工程化

为什么要学TS

TypeScript Vs JavaScript

TypeScriptJavaScript
JavaScript的超集,用于解决大型项目的代码复杂性—种脚本语言,用于创建动态网页
强类型,支持静态和动态类型动态弱类型语言
可以在编译期间发现并纠正错误只能在运行时发现错误
不允许改变变量的数据类型变量可以被赋值成不同类型

image.png

TypeScript带来了什么

  • 类型安全
  • 下一代JS特性
  • 完善的工具链

TypeScript不仅仅是一门语言,更是生产力工具。

TypsScript推荐

  • Awesome Typescript: TS开源教程及应用
  • Typescript Playground: TS到JS在线编译

TypeScript基础

基础类型

  1. boolean、number、string
  2. undefined、null
  3. any、unknown、void
  4. never
  5. 数组类型[]
  6. 元组类型tuple

代码示例(部分):

function test(x:string | number): boolean {
    if(typeof x ==='string'){
        return true;
    }else if(typeof x ==='number'){
        return false;
    }
    return throwError("参数格式不对");
}
function throwError(message: string): never{
    throw new Error(message);
}

函数类型

定义︰TS定义函数类型时要定义输入参数类型和输出类型
输入参数︰参数支持可选参数和默认参数
输出参数︰输出可以自动推断,没有返回值时,默认为void类型
函数重载︰名称相同但参数不同,可以通过重载支持多种类型

代码示例(部分):

function add(x: number[]): number
function add(x: string[]): string
function add(x: any[]): any {
    if(typeof x[0] === 'string'){
    return x.join()
    }
    if (typeof x[0] === 'number'){
    return x.reduce((acc,cur) =>acc + cur)
    }
)

interface

定义∶接口是为了定义对象类型
特点:

  • 可选属性︰?
  • 只读属性:readonly
  • 可以描述函数类型
  • 可以描述自定义属性

总结:接口非常灵活duck typing 代码示例(部分):

interface Person {
    name: string
    age: number
}
const p1: Person = {
    name : "lin" ,
    age: 18
}

当你使用这个变量时能看到类型提示:

image.png 对于没有使用的属性名,可以使用propName

interface RandomkRey {
    [propName: string]: string
}

const obj: RandomHey = {
    a: "hello",
    b: "world",
    c: "typescript",
}

定义︰写法和JS差不多,增加了一些定义
特点:

  • 增加了public、private、protected修饰符
  • 抽象类∶
    • 只能被继承,不能被实例化
    • 作为基类,抽象方法必须被子类实现
    • interface约束类,使用implements关键字

代码示例:

class Persan{
    protected name: string
    private sex: string
    public constructor(nane: string) {
        this.nane = name
        this.sex = "male"

class Student extends Person{
    study(){
    console.log(this.name);
    console.log(this.sex);//Property 'sex' is private and only accessible within class 'Person'.
    } 
}
    
let person = new Person("daming");
person.nane //Praperty 'name' is protected and only accessible within class 'Person' and its subclasses.
person.sex //Property 'sex' is private and only accessible within class 'Person'.

TypeScript进阶

高级类型

  • 联合类型|
  • 交叉类型&
  • 类型断言
  • 类型别名(type VS interface)
    • 定义∶给类型起个别名
    • 相同点:
      • 都可以定义对象或函数
      • 都允许继承
    • 差异点:
      • interface是TS用来定义对象,type是用来定义别名万便便用;
      • type可以定义基本类型,interface不行;
      • interface可以合并重复声明,type不行;

泛型

基本定义:

  • 泛型的语法是◇里面写类型参数,一般用T表示;
  • 使用时有两种方法指定类型:
    • 定义要使用的类型
    • 通过TS类型推断,自动推导类型

代码示例:

function print<T>(arg:T):T{
    console.log(arg)
    return arg
}
print<string>("hello") //定义T为string
print("hello") // TS类型推断,自动推导类型为string

泛型工具类型-基础操作符

  • typeof:获取类型
interface Person {
    name: string;
    age: number;
}

const sem: Person = { name : "semlinker",age: 30 };
type sem = typeof sem; // type Sem = Person
  • keyof:获取所有键
interface Person{
    name: string;
    age: number;
}

type K1 = keyof Person;//"name" | "age"
type k2 = keyof Person[]; //"length" | "toString" | "pop" |"push" | "concat" | "join"
  • in:遍历枚举类型
type keys = "a" | "b"| "c"
    type 0bj ={
[p in keys]: any
} //-> { a: any, b: any, c: any }
  • T[K]:索引访问
interface IPerson{
    name: string;
    age : number;
}

let type1: IPerson['name'] //string
let type2: IPerson['age'] //number
  • extends:泛型约束
interface Lengthwise {
    length: number;
    function loggingIdentity<T extends Lengthwise>(arg: T):T {
        console.log(arg.length);
        return arg;
}

loggingIdentity({value:3})
loggingIdentity({length:5})

泛型工具类型-常用工具类型

  • Partial:将类型属性变为可选
  • Required:将类型属性变为必选
  • Readonly:将类型属性变为只读
  • Pick、Record... 代码示例:
type Partial<T> = {
    [P in keyof T]?: T[P];
};
type Reguired<T> = {
    [P in keyof T]-?: τ[P]
};
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};

实战&工程化

声明文件

  • declare:三方库需要类型声明文件
  • .d.ts:声明文件定义
  • @types:三方库TS类型包200
  • tsconfig.json: 定义TS的配置
import axios from 'axios'
    
interface API {
    '/book/detail': {
    id: number,
    },
    '/book/comment': {
    id: number
    comment: string
    }
}

function request<T extends keyof API>(url: T, obj: API[T]) {
    return axios. post(url, obj)
}
request('/book/comment', {
    id: 1,
    comment: '非常棒!'
})
   
//路径错误    
request('/book/test', {
    id: 1,
    comment: '非常棒!'
})
    
//参数错误
request('/book/detail', {
    id: 1,
    comment:'非常棒!',
})

课程总结:

image.png