【青训营前端进阶班笔记】第五节 TypeScript入门

88 阅读4分钟

简单介绍

JavaScript是动态类型的弱类型语言

TypeScript是静态类型的弱类型语言

静态类型的优势

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

基础语法

基础类型

在定义变量时,在变量后加上:变量名称

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

对象类型

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;
}

/*报错:无法分配到"jobId",因为它是只读属性*/
bytedancer.jobId 12345; 
/*成功:任意属性标注下可以添加任意属性*/
bytedancer.plateform = 'data';
/*报错:缺少属性"name",hobby可缺省*/ 
const bytedancer2: IBytedancer {
    jobId: 89757, 
    sex: 'woman', 
    age: 18,
}

函数类型

函数类型也是直接在定义的函数名称后面指明:函数类型

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;
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=[1,2,3,4,5,6];
const arr2:IArr2=[1,2,'3','4',{a:1}]; 
const arr3:IArr3 = [1,2,'3,'4];
const arr4:IArr4 = ['string',()=>null,{},[]]

TypeScript补充类型

/*空类型,表示无赋值*/ 
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';

TypeScript泛型

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

我们希望这里的target可以是任意的类型,我们传入什么类型,函数就返回什么类型的数组

如果这里像这样使用any type IGetRepeatArr (target:any)=>any[]; 可以编译通过,但是并不符合我们的需求。因为这里传入的是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);
/*报错:类型“numbe r”的参数不能赋给类型“string”的参数*/
getstrArr(123);

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

类型别名和类型断言

/*通过type关键字定义了IObjArr的别名类型*/ 
type IObjArr = Array<{
    key:string;
    [objKey:string]:any;
}>
function keyBy<T extends IObjArr>(objArr:Array<T>){
/*未指定类型时,result类型为{}*/
const result = objArr.reduce((res,val,key)=> 
    res[key]val;
    return res;
},{});
/*通过as关键字,断言result类型为正确类型*/ 
    return result as Record<string,T>;
}

字符串/数字 字面量

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

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

高级类型

联合/交叉类型

  • 联合类型:A|B;联合类型表示一个值可以是几种类型之一
  • 交叉类型:A&B;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性

image.png