什么是 TypeScript 主流
发展历史 => 略微了解一下就好
为什么是TS?
- JS:动态类型、弱类型语言 动态类型 => 执行阶段才进行变量类型的匹配
- TS: 静态类型、弱类型语言 静态类型 => 提前进行变量类型的匹配
可读性增强
可维护性增强 => 编译阶段就会暴露大部分错误 => 适合多人共同维护项目
JS 超集 => 支持渐进式引入与升级 + 包含所有JS特性
基本语法
/*字符串*/
const q = 'string'
/*同样是字符串类型的变量 TS提前做了变量的类型定义*/
const q:string = 'string'
对象类型
const bytedancer:IBytedancer = {
/*手动创建一个类型*/
jobId:930245,
name:'zeng',
sex:'man',
age:28,
hobby:'swimming',
}
interface IBytedancer {
/*只读属性: 约束属性不可在对象初始化外赋值*/
readonly jobId:number;
name:string;
sex:'man'|'woman'|'other';
age:number;
/*可选属性: 定义该属性可以不存在*/
hobby?: string;
/*任意属性: 约束所有对象属性都必须是该属性的子类型*/
[key:string]: any;
}
📌 readonly 标记的属性只能在声明时或类的构造函数中赋值
const user : Readonly<USER> = {
name: 'zhb',
age: 23
}
user.name = 'zzz' // error => name属性只可读
数组类型
/*类型 + 方括号*/
type IArr1 = number[];
/*泛型表示*/
type IArr2 = Array<string | number | Record<string,number>> // 尖括号内就是数组元素的类型
//---------------------------------
/*原始表示*/
type IArr3 = [number,string,number];
/*接口表示*/
interface IArr4 = {
[key:number]:any;
}
/*Record:以 typeof 形式创建一个类型,包含一组指定的属性且必填*/
type example = Record<'x'|'y',number>;
=> 等同于
type example = {
x:number;
y:number;
}
TS 泛型 => 不预先指定变量的类型,在使用的时候再指定类型的一种特性
-
泛型约束:限制泛型必须符合字符串
type IGetRepeatStringArr = <T extends string>(target: T) => T[]; const getStrArr = IGetRepeatStringArr = target => new Array(100).fill(target); getStrArr(123);// error 传参类型不匹配 -
泛型参数默认类型
type IGetRepeatArr<T = number> = (target: T) => T[]; const getStrArr = IGetRepeatStringArr = target => new Array(100).fill(target); getStrArr('123');// error -
类型别名 & 类型断言
函数重载
- 📚 首先,重载是指方法名字相同,参数不同,返回类型可以相同也可以不相同
- 每个重载的方法(或者构造函数) 都必须有一个独一无二的参数类型列表
=> 范围问题 => 将自定义变量的范围大于匿名函数的范围
// 示例
function disp(string):void;
function disp(number):void;
// 进阶案例
/* 对getDate函数进行重载,timestamp可为缺省参数*/
function getDate(type:'string',timestamp?:string):string;
interface IGetDate{
(type:'string',timestamp?:string):string;
(type:'string',timestamp?:string):Date;
(type:'string'|'date',timestamp?:string):Date | string;
}
const getDate2:IGetDate = (type,timestamp)=>{
const date = new Date(timestamp);
return type === 'string'? date.toLocaleString():date;
}
让我们看看报错信息 👁️
从图中我们可以看到,ts自动对我们的timestamp变量类型做了判断,但是这个判断并不符合,这也就是上面提到的变量范围的原因,我们要将声明变量中的范围大于匿名函数中变量的范围即可。
TypeScript 高级类型
联合/交叉类型
- 联合类型
- "IA | IB":表示一个值可以是几种类型之一
- 交叉类型
- "IA & IB":多种类型叠加到一起成为一种类型,它包含了所需的所有类型的所有特性
- 具体实例
// 原始声明 const bookList = [{ author:'xiaoming', type:'history', range:'2001-2021', },{ author:'xiaoli', type:'story', theme:'love' }] // ------------ type IBookList = Array<{ // 公共类型 author:string, } & ({ type:'history'; range:string; } | { type:'story'; theme:string; })
类型保护与类型守卫
类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域
interface IA{a:1,a1:2}
interface IB{b:1,b1:2}
function getIsIA(args:IA|IB):arg is IA{
return !!(arg as IA).a;
}
function log2(args:IA|IB){
if(getIsIA(arg)){
console.log(arg.a1)
}else{
console.log(arg.b1)
}
}
TypeScript 工程应用
Webpack
- loader => 实现对ts文件的编译和检查
Node.js
- 使用TSC编译 🔍code.ts => TSC(code.ts) => code.js