这是我参与「第五届青训营 」伴学笔记创作活动的第5天,学习的是关于TypeScript的语法与数据类型。
TypeScript的发展历程
- 2012-10:微软发布了TypeScript第一个版本(0.8)
- 2014-10:Angular 发布了基于TypeScript的2.0版本
- 2015-04:微软发布了Visual Studio Code
- 2016-05:@ ty pes/react发布,TypeScript 可开发React
- 2020-09:Vue 发布了3.0 版本,官方支持TypeScript
- 2021-11:v4.5版本发布
选择TypeScript的原因
JS与TS的关系:
1.联系:TypeScript 是 JavaScript 的语法超集,它添加了静态类型。
2.区别:
区分动态与静态:是否提前编译流程
TS的优势
静态类型
- 可读性增强:基于语法解析TSDoc,ide增强;
- 可维护性增强:在编译阶段暴露大部分错误
- 多人合作的大型项目中,获得更好的稳定性和开发效率
JS的超集
- 包含于兼容所有Js特性,支持共存
- 支持渐进式引入与升级
编辑器推荐
Visual Studio Code、TS官网
基本语法
1.基础数据类型
*字符串*/
const q='string';
/*数字*/
const w=1;
/*布尔值*/
const e=true;
/*null*/
const r=null;
/*undefined*/
const t=undefined;
2.对象类型
interface IAhu{
/*只读属性*/
readonly SID:number;
name:string;
sex:'boy'|'girl'|'other';
age:number;
/*可选属性*/
hobby?:string;
/*任意属性:约束所有对象属性都必须是该属性的子类型*/
[key:string]:any;
}
3.函数类型
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;
4.数组类型
/*类型+方括号 表示*/
type IArr1=number[];
/*范类型表示*/
type IArr2=Array<string|number|Record<string,number>>;
/*元组表示*/
type IArr3=[number,number,string,string];
/*接口表示*/
interface IArr4{
[key:number]:any;
}
5.TypeScript泛型
不预先指定具体的类型,而在使用时再指定类型的一种特性。
function getRepeatArr(target){
return new Array(100).fill(target);
}
type IGetRepeatArr=(target:any) => [];
type IGepeatArrR=<T>(target:T) => T[];
高级类型
1.联合/交叉类型
例如:为书籍列表编写类型
- 原方法:类型声明繁琐,存在较多重复
interface IScience{
author:string;
type:string;
}
interface IDetection{
author:string;
type:string;
}
type IBookList=Array<IScience|IDetection>;
- 改进
-
联合类型:IA|IB;联合类型表示一个值可以是几种类型之一 -
交叉类型:IA&IB;多种类型叠加到一起成为一种类型,它包含所需的所有类型的特性
type IBookList=Array<{
author:string;
}&({
type:'Science Fiction';
} |{
type:'Detection';
})>
2.类型保护与类型守卫
例子代码如下:
interface IA{a:1,a1:2}
interface IB{b:1,b1:2}
function log(arg:IA|IB){
if (arg.a){
console.log(arg.a1)
} else{
console.log(arg.b1);
}
}
结论:
访问联合类型时,处于程序安全,仅能访问联合类型中的交集部分。
对例子代码进行改造: 定义一个函数,返回值是一个类型谓词,生效范围为子作用域
function getIsIA(arg:IA|IB):arg is IA{
return !!(arg as IA ).a;
}
function log2(arg:IA|IB) {
if (getIsIA(arg)){
console.log(arg.a1)
} else{
console.log(arg.b1)
}
}
3.Merge 函数类型实现
例子代码如下:
function merge1(sourceObj, targetobj){
const result={…source0bj };
for(let key in targetobj){
const iteuVal = sourceobj [key];
itemVal &&( result[key] itemVal );
}
return resutt;
function merge2(sourceobj, targetobj){
return {..source0bj, ...target0bj};
}
为以上函数编写类型:
interface ISourceObj{
x?: string;
y?: string;
}
interface ITargetobj{
x: string;
y: stringl;
}
type IMerge =(source0bj: ISource0bj, targetobj:
ITargetobj)> ITargetobj;
结论:
- 类型实现繁琐:若obj类型较为复杂,则声明 source和taget便需要大量重复2遍
- 容易出错:若 target增加/减少key,则需要 source联动去除。 通过泛型实现:
incerface IMerge{
<T extends Record<string, any>>( source0bj:Partial<T>, targetobj: T): T;
}
type IPartial<T extends Recordestring, anys>> ={
[P in keyof T]?: T[P];
}
结论:
- 索引类型:关键字【keyof】,其相当于取值对象中的所有key组成的字符串字面量如: type IKeys= keyof{ a: string; b: number } ;
- 关键字【in】,其相当于取值字符串字面量中的一种可能,配合泛型P即表示每个key;
- 关键字【?】,通过设定对象可选选项,即可自动推导出子集类型。
4.函数返回值类型
- 实现函数delayCall的类型声明
- delayCall接受一个函数作为入参,其实现延迟1s运行函数
- 其返回promise,结果为入参函数的返回结果
function delayCall( func) {
return new Promise( resolve =>{
setTimeout(()=> {
const result = func();
resolve( result);
},1000);
});
}
TypeScript 工程应用
1. web——webpack
- 配置webpack loader相关配置
- 配置tsconfig.js文件
- 运行webpack启动or打包
- loader处理ts文件时,会进行编译与类型检查
2. node——使用TSC编译
- 安装node与npm
- 配置tsconfig.js文件
- 使用npm安装tsc
- 使用tsc运行编译得到js文件