前言
此专栏会讲解ts基本使用以及在vue3中的使用方式
1.TypeScript 的介绍
- JavaScript的超集,在JavaScript的基础上添加了可选的静态类型和基于类的面向对象编程。
- TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。
- TypeScript通过TypeScript编译器或Babel转译为JavaScript代码,可运行在任何浏览器,任何操作系统。
- TypeScript 起源于使用JavaScript开发的大型项目 。由于JavaScript语言本身的局限性,难以胜任和维护大型项目开发。因此微软开发了TypeScript ,使得其能够胜任开发大型项目。
2.TypeScript优缺点
优点:
- 增强代码的可维护性,应用于大型项目时效果显著
- 友好的错误提示,编译阶段就能检测类型从而发现大部分问题
- 支持最新的JavaScript新特性
缺点:
- 需要一定的学习成本
- 增加项目前期的开发成本,但对于一个需要长期维护的项目来说,此举无疑是必要的
- 一些库对ts支持不完美。随着时间的推移,这个问题会越来越小,越来越多的库对ts提供了支持
3.安装环境
打开cmd命令行输入指令全局安装ts(因为是全局安装,cmd打开哪个文件都可以)
npm install -g typescript
验证是否安装成功输入指令,如果输出ts版本号,证明安装成功了
tsc -v
4.编译ts文件
手动编译:
新建一个学习目录``tsStudy,并在目录内新建一个ts文件,例如:
helloWord.ts```
因为ts兼容js语法,所以我们用熟悉的js语法书写一段代码如下
const str ="hello word"
console.log(str)
ts代码不能直接运行,需要编译成js,然后通过浏览器或node环境运行
执行命令编译成js:tsc 加上你要编译的ts文件路径
tsc ./helloWods.ts
这是会生成一个和你ts文件名臣相同的js文件。里面的内容如下
var str = "holle word";
console.log(str);
至此手动编译就完成了
自动编译
如果每次修改完文件后都去手动编译,这样十分浪费咱们的时间。
输入指令初始化ts工程配置,会生成tsconfig.json
tsc -init
新建js文件,用来存储编译后的文件
tsconfig.json内修改参数:
outDir:"./js"
(编译后的js文件存储位置)
strict:flase
(不使用js严格模式)
点击上方任务栏->终端->运行任务->tsc监视
如果没显示tsc监视的话就点击下方显示所有任务或typescript,就会出现tsc监视任务
配置完之后就当你再操作修改ts文件后,js文件夹内的js文件就会对应更改
5、ts特性展示
静态类型检查:
js中编码:
let num=12345
console.log(num.length)//undefined
当你将以上代码运行到浏览器或node环境时,会打印undefined
,因为这段代码错误的将string类型的方法运用到了number类型变量上。在代码量较大时,不容易辨别出这个问题。
在ts中使用这段编码,他会在编辑器内直接告诉你问题所在,这就是静态类型检测。
检验未正确的调用方法:
js中
let num=123456;
console.log(ab.toString==="123456")//很明显toString方法中少了()执行,但是并没有给出提示
浏览器输出
ƒ trim() { [native code] }
能正常输出,但是这不是我们想要的,没有告诉我们问题在哪;
ts中:
明确给出了注释
ts还有很多特性,在稍后的学习中慢慢去体会。
6、TS基础类型
变量声明关键字:var(不推荐),let。常量声明关键字const,这里和js是保持一直的;
各种类型的各种方法(例如string类型的.length,slice,substr等等)也和js保持一直,下面就不一一赘述;
变量和常量的声明后面需加上 :类型
,可能有同学有疑问上述例子中也没有添加变量啊?也可以使用,这是因为ts特性类型推论(type inference)
,在声明变量赋值时,若果未添加上类型,他会根据你所赋的值的类型给变量添加上,后续在详细说明。
布尔值 boolean
let isShow:boolean=false;
isShow=123456;// error 不能将类型“123”分配给类型“boolean”
ts特性:当变量被赋予某一类型后,后续给此变量赋值时,只能赋予此类型的值,例如上方案例,声明为boolean类型的值,赋予number类型的值后,编辑器就会友好提示你不能赋值,并说明原因。
数字 number
和JavaScript一样,TypeScript里的所有数字都是浮点数。 这些浮点数的类型是number
。 除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;
字符串 string
和JavaSciprt一样,ts中也使用string表示文本数据类型,使用单引号、双引号、反引号(模板字符串)去表示字符串
还可以使用模板字符串例:
let time:string='晚上八点'
let tvName:string="还珠格格"
let say:string=`安吉拉,今天${time},来我家看${tvName}`
console.log(speed)// 安吉拉,今天晚上八点,来我家看还珠格格
当然了,也能做我们所熟悉的字符串拼接
let name:string='小明'+"和"+"小李"
数组 array
TypeScript像JavaScript一样可以操作数组元素。 有两种方式可以定义数组。
//第一种,可以在元素类型后面接上[],表示由此类型元素组成的一个数组:
const list: number[] = [1, 2, 3];
//第二种方式是使用数组泛型,Array<元素类型>:
const list2: Array<number> = [1, 2, 3];
两种声明方式都可以,下面注意一个点:
当给数组变量赋予类型后,再
//我们声明一个数组里的元素为string类型
let strList:Array<string>=['字符串1','字符串2','字符串3',]
//修改其中一个变量
strList[0]=1;//error 不能将1分配给类型“string” ,这时更改数组内的元素时,同样是只能赋初始类型的值
问题来了,我想在同一个数组内,赋予数组内不同类型的值该怎么办?元组解决了这个问题
元组 Tuple
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为string
和number
类型的元组。
let x:[string,number];
x=['hello',12];//ok
x=[12,'hello'] //error
当访问一个已知索引的元素,会得到正确的类型:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
枚举 enum
enum
类型是对JavaScript标准数据类型的一个补充。(相当于代码注释,使代码拥有更多的语义)
//定义一个枚举
enum Color{
green,
bule,
red
}
console.log(Color.green) //0
console.log(Color.bule) //1
console.log(Color.red) //2
按上述代码书写,并没有给枚举Color内属性green,bule,red赋值,他们会按照从0开始依次递增的方式来规则来赋默认值
enum Color{
green=4, //4
bule,//5
red//6
pink=9,//9
yellow//10
}
如果给第一个元素赋予了一个number值,后续未赋值的元素会按照上一个值加1的值来赋初始值;
当然也能够全部手动赋值
enum userType{
normalUser=1,
admin=4,
superAdmin=8
}
枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
alert(colorName); // 'Green'
总结:合理的使用枚举,会使后期的维护工作减少很多,这相比于写注释来说更直观一些
任意值 any
有时候,我们会想要为那些在编程阶段还不清楚类型的变量
指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用any
类型来标记这些变量:
let notSure: any = 4;
notSure = "我也可以是个字符串";
notSure = false; // 也可以是个boolean值,任何类型我都能接受
在对现有代码进行改写的时候,any
类型是十分有用的,它允许你在编译时可选择地包含或移除
类型检查。并且当你只知道一部分数据的类型时,any
类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:
let list: any[] = [1, true, 'free']
list[1] = 100
使用any,相当于放弃了TS特性类型检查。当你清楚一个变量的类型请不要使用any,如果这样的话和写js没什么区别,请不要写满是any的垃圾代码去攻击你同事
的脑细胞。
void
某种程度上来说,void
类型像是与any
类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是void:
function warnUser(): void {
alert("当函数没有返回值时使用void声明");
}
声明一个void
类型的变量没有什么大用,因为你只能为它赋予undefined
和null
:
let unusable: void = undefined;
Null 和 Undefined
TypeScript里,undefined
和null
两者各自有自己的类型分别叫做undefined
和null
。 和void
相似,它们的本身的类型用处不是很大:
//我们不能为这些变量分配太多其他变量
let u: undefined = undefined;
let n: null = null;
默认情况下null
和undefined
是所有类型的子类型。 就是说你可以把null
和undefined
赋值给number
类型的变量。
然而,当你指定了--strictNullChecks
标记,null
和undefined
只能赋值给void
和它们各自。 这能避免很多常见的问题。
可以在项目的tsconfig.json文件中启用strictNullChecks
编译器选项
在TS中,为了各版本的兼容,strictNullChecks的默认值是false
{
"compilerOptions": {
"strictNullChecks": true
// ...
}
}
Never
never
类型表示的是那些永不存在的值的类型。 例如,never
类型是那些总是会抛出异常
或根本就不会有返回值
的函数表达式或箭头函数表达式的返回值类型; 变量也可能是never
类型,当它们被永不为真的类型保护所约束时。
never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使any也不可以赋值给never。
下面是一些返回never类型的函数:
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
本文多处摘录typeScript中文手册,感谢TS翻译团队作出的贡献