TypeScript入门
这是我参与第五届青训营伴学笔记创作的第3天。
课程重点内容
- 为什么什么是TypeScript
- TS的基本语法
- TS的高级类型
- TS在工程中的应用
为什么什么是TypeScript
1.动态类型与静态类型: 动态类型:执行时根据变量值确定类型。代表语言:JS。静态类型:在编译时根据声明类型确定。代表:TS。
2.强类型与弱类型: 强类型编译前就把数据类型确定了,被确定了数据类型的变量,如果不强制转换,就永远是给定的数据类型。弱类型是在编译后确定数据类型,没有明显的类型,它随着环境的不同,自动变换类型。
3.相较于JS,TS的特点: 静态类型语言相较于js,ts编写的代码可读性增强,并且在编译阶段就暴露出大部分错误,故维护性较强,适合多人合作的大型项目。js的超级ts包含于兼容所有js特性,支持共存,支持渐进式引入与升级。
TS的基本语法
- 基础数据类型:string,number,boolean,null,undefined
- 对象类型:
方式一 直接在定义函数时补充类型:
function mult(a:number,b:number):number{
return a*b;
}
方式二 与对象类型定义类似,用interface关键字定义函数类型
interface Mult {
(x:number,y:number):number
}
const add:Mult = (a,b)=>{
return a+b;
}
-
函数重载:
-
数组类型:
-
泛型:
因为在软件工程中,我们不仅要创建一致的定义良好的api,同时要考虑重用性,期望组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,泛型的设计就可以创建可重用的组件,达到我们的目的。 如下我们定义了一个泛型函数:
type GetArr=<T>(target:T)=>T[]
const getarr:GetArr=(target)=>{
return new Array(10).fill(target);
}
可以通过泛型,在不同场景下调用函数时绑定不同的参数类型
const arr=getarr<number>(1);
const arr2=getarr<string>("hello");
TS的高级类型
我们先来看一个例子:要实现merge函数类型,要求sourceObj必须为targetObj的子集
function merge(sourceObj,targetObj){
return {...sourceObj,...targetObj}
}
于是我们很容易这样定义:
interface ISourceObj{
a?:string;
b?:string;
}
interface ITargetObj{
a:string;
b:string;
}
type IMerge=(sourceObj:ISourceObj,targetObj:ITargetObj)=>ITargetObj
这样写会造成类型实现繁琐:若obj类型过于复杂,则声明source和target便需要大量重复2遍,而且容易出错,若target增加减少key,则需要source联动去除。
为了优化类型定义,我们可以利用TS内置的工具类型:将T中的所有属性设置为可选
type Partial<T> = {[P in keyof T]?:T[P]|undefined}
merge函数类型就可以如下定义:
type IMerge=<T extends Record<string,any>>(sourceObj:Partial<T>,targetObj:T)=>T;
TS在工程中的应用
在Web中应用
- webpack loader相关配置:由于webpack默认只能识别打包.js文件,其它后缀名的文件需要相关loader来处理。
- 配置tsconfig.js文件:编译配置。
- 运行webpack启动,打包。
- loader处理ts文件时,会进行编译和类型检查。
在Node中应用
- 安装Node与npm.
- 配置tsconfig.js文件。
- 使用npm安装tsc
- 使用tsc运行编译得到js文件。
总结
项目中使用ts的确会使代码量增多,但会对生产效率有很大提升作用(虽然目前自己由于缺乏ts相关项目经验还未体会到😅)。据说“自从用了TS后,会再也不想用JS了”。