TypeScript|青训营笔记

71 阅读5分钟

TypeScript|青训营笔记

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

image.png

typescript发展史

  • 2012-10:微软发布了typescript第一个版本
  • 2014-10:Angular发布了基于typescript的2.0版本
  • 2015-04:微软发布了vs-code
  • 2016-05:@types/react,typescript可开发react
  • 2020-09:vue3.0版本,官方支持typescript
  • 2021-11:v4.5版本发布 typescript是静态类型语言和弱类型语言,与JavaScript相反
  • 静态类型 可读性增强:基于语法解析TSDoc,ide增强

可维护性增强:在编译阶段暴露大部分错误

  • js超集 包含于所有的js特性,支持共存

支持渐进式引入与升级

基本语法

基本数据类型

const q: string = 'string';      //字符串
const w: number = 1;             //数字
const e: boolean = true;         //布尔值
const r: null = null;            //null
const t: undefined = undefined;  //undefined

对象类型

const bytedancer: IBytedancer = {
    jobId: 9303245,
    name: 'Lin ' ,
    sex: 'man ' ,
    age: 28,
    hobby: 'swimming ',
}

自定义类型:

interface IBytedancer {
/*只读属性:约束属性不可在对象初始化外赋值*/
    readonly jobId: number;
    name: string;
    sex: 'man' | 'woman' | 'other';
    age: number;
    /*可选属性:定义该属性可以不存在*/
    hobby? : string;
    /*任意属性:约束所有对象属性都必须是该属性的子类型*/
    [key: string] : any;
}

函数类型

类型声明代码

  1. 直接在函数上进行类型的补充
  2. 给函数的变量赋值一个函数类型声明
function add(x:number, y: number): number {
    return x + y;
}
const mult: (x:number, y: number) => number = (x,y) => x * y;

函数也支持interface来定义类型

interface IMult {
    (x: number, y: number) : number;
}
const mult: IMult =(x,y) => x * y;

函数重载

/*对getDate函数进行重载,timestamp为可缺省参数*/
function getDate(type: 'string', timestamp?: string): string;
function getDate(type: 'date' , timestamp?: string): Date;
function getDate(type: 'string' | 'date', timestamp?: string): Date | string{
    const date = new Date(timestamp);
    return type === 'string' ? date.toLocaleString() : date;
}

const x = getDate( 'date');// x: Date
const y = getDate( 'string', '2018-01-10' );// y: string

简化后(interface)定义一个匿名函数,把函数自变量赋值给getData2,同时约定类型为IGetData,存在一个类型匹配

interface IGetDate {
    (type: 'string ', timestamp?: string): string
    (type: 'date', timestamp?: string): Date;
    (type: 'string' | 'date', timestamp?: string): Date | string;}
/*不能将类型“(type: any,timestamp: any) => string | Date"分配给类型"IGetDate"。
    不能将类型"string | Date"分配给类型“string”。
        不能将类型"Date”分配给类型"string"。ts (2322)*/
const getDate2: IGetDate = (.type, timestamp) => {
    const date = new Date(timestamp);
    return type === 'string' ? date.toLocaleString() : date;
}

数组类型

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

const arr1: IArr1 = [1234,5,6];
const arr2: IArr2 = [12'3', '4', { a: 1 }];
const arr3: IArr3 = [12'3','4'];
const arr4: IArr4 = [ 'string' , () => null, {}, []];

类型补充:空类型,任意类型,枚举类型

/*空类型,表示无赋值*/
type IEmptyFunction = () => void;
/*任意类型,是所有类型的子类型*/
type IAnyType = any;
/*枚举类型:支持枚举值到枚举名的正、反向映射*/
enum EnumExample {
    add = '+',
    mult = '*',
}
EnumExample [ 'add ' ] === '+';
EnumExample [ '+'] === 'add ';

enum ECorlor { Mon,Tue,wed,Thu,Fri, Sat,Sun };
ECorlor [ 'Mon' ] === 0;
ECorlor[0] === 'Mon ' ;
/*泛型*/
type INumArr = Array<number>;

泛型:传入的参数填充到数组,特征就是不预先指定数据类型的时候去使用,类型是在使用的时候才指定说明使用,具体实现如下:

function getRepeatArr(target) {
    return new Array ( 100).fill(target);
}

type IGetRepeatArr = (target: any) =>any [];

/*不预先指定具体的类型,而在使用的时候再指定类型的一种特性*/
type IGetRepeatArrR =<T>(target: T)=> T[];

泛型的其他场景

/*泛型接口&多泛型*/
interface IX<T,U>{
    key: T;
    val: U;
}
/*泛型类*/
class IMan<T>{
    instance: T;
}
/*泛型别名*/
type ITypeArr<T>= Array<T>;

泛型的两个高级语法

/*泛型约束:限制泛型必须符合字符串*/
type IGetRepeatStringArr = <T extends string>(target: T) => T[];
const getStrArr: IGetRepeatStringArr = target => new Array(100).fill(target);
/*报错:类型"“number”的参数不能赋给类型“string"的参数*/
getStrArr(123);

/*泛型参数默认类型*/
type IGetRepeatArr<T = number> = (target: T) =>T[];
const getRepeatArr: IGetRepeatArr = target => new Array(100).fill(target);
/*报错:类型"string"的参数不能赋给类型"number"的参数*/
getRepeatArr( '123');

字符串/数字 字面量

/*允许指定字符串/数字必须的固定值*/

/* IDomTag必须为html、body、div、span中的其一*/
type IDomTag = 'html' | ' body' | 'div' | 'span';
/* IOddNumber必须为1、3、5、7、9中的其一*/
type IOddNumber = 1 | 3 | 5 |7 | 9;

高级类型

联合/交叉类型

interface IHistoryBook {
    author: string;
    type: string;
    range: string
}
interface IStoryBook {
    author: string;
    type: string;
    theme: string;
type lBookList = Array<IHistoryBook | IStoryBook>;

上面为书籍编写类型,类型生命较为繁琐,存在较多重复。下面为改进代码

  • 联合类型: IA|IB;联合类型表示的值可以是几种类型之一
  • 交叉类型:IA&IB;多种类型叠加到一起成为一种类型,他包含了所需的所有类型特征
type lBookList = Array<{
    author: string;
} &({
    type: 'history';
    range: string;
}|{
    type: 'story';
    theme: string;
})>

类型保护与类型守卫

interface IA { a: 1, a1: 2 }
interface IB { b: 1, b1: 2 }

/类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域*/
function getlslA(arg: IA | IB): arg is IA {
    return !(arg as lA).a;
}
function log2(arg: IA | IB){
    if (getlslA(arg)) {
    console.log(arg.a1)
    } else {
        console.log(arg.b1);
    }
}

工程应用

webpage

  1. 配置webpage,loader相关配置
  2. 配置tsconfig.js文件
  3. 运行webpage启动/打包
  4. loader处理ts文件。会进行编译和类型检查

使用TSC编译

  1. 安装node与npm
  2. 配置tsconfig.js文件
  3. 使用npm安装tsc
  4. 使用tsc运行编译得到js文件