一、TypeScript简介
1、定义
-
TypeScript,简称为TS,是JS的超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发,代码开源于GitHub上。
-
Vue3.0就是使用TS开发出来的,并且推荐开发者使用TS进行开发。
2、特征
-
类型系统
1.TypeScript是静态类型: 类型系统按照「类型检查时机」来分类,可以分为动态类型和静态类型。 动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。JS是一门解释型语言,没有编译阶段,所以JS是动态类型。 2.TypeScript 是弱类型: 类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型,TS是完全兼容JS的,它不会修改JS运行时的特性,所以它们都是弱类型。 例子: console.log(1 + '1'); // 打印出字符串 '11', ts和js都不会报错 //对象+对象是 toString 后相加的 print(1 + '1') Python 是强类型会报错 # TypeError: unsupported operand type(s) for +: 'int' and 'str'
-
适用于任何规模
1.TypeScript 非常适用于大型项目——这是显而易见的,类型系统可以为大型项目带来更高的可维护性,以及更少的 bug。 2.在中小型项目中推行 TypeScript 的最大障碍就是认为使用 TypeScript 需要写额外的代码,降低开发效率。但事实上,由于有[类型推论],大部分类型都不需要手动声明了。相反,TypeScript 增强了编辑器(IDE)的功能,包括代码补全、接口提示、跳转到定义、代码重构等,这在很大程度上提高了开发效率。而且 TypeScript 有近百个[编译选项],如果你认为类型检查过于严格,那么可以通过修改编译选项来降低类型检查的标准。 3.TypeScript 还可以和 JavaScript 共存。这意味着如果你有一个使用 JavaScript 开发的旧项目,又想使用 TypeScript 的特性,那么你不需要急着把整个项目都迁移到 TypeScript,你可以使用 TypeScript 编写新文件,然后在后续更迭中逐步迁移旧文件。如果一些 JavaScript 文件的迁移成本太高,TypeScript 也提供了一个方案,可以让你在不修改 JavaScript 文件的前提下,编写一个[类型声明文件],实现旧项目的渐进式迁移。 4.就算你从来没学习过 TypeScript,你也可能已经在不知不觉中使用到了 TypeScript——在 VSCode 编辑器中编写 JavaScript 时,代码补全和接口提示等功能就是通过 TypeScript Language Service 实现的 5.一些第三方库原生支持了 TypeScript,在使用时就能获得代码补全了,比如 Vue 3.0 React
-
与标准同步
1.TypeScript 的另一个重要的特性就是坚持与 ECMAScript 标准同步发展。 ECMAScript 是 JavaScript 核心语法的标准,自 2015 年起,每年都会发布一个新版本,包含一些新的语法。 一个新的语法从提案到变成正式标准,需要经历以下几个阶段: Stage 0:展示阶段,仅仅是提出了讨论、想法,尚未正式提案。 Stage 1:征求意见阶段,提供抽象的 API 描述,讨论可行性,关键算法等。 Stage 2:草案阶段,使用正式的规范语言精确描述其语法和语义。 Stage 3:候选人阶段,语法的设计工作已完成,需要浏览器、Node.js 等环境支持,搜集用户的反馈。 Stage 4:定案阶段,已准备好将其添加到正式的 ECMAScript 标准中。 一个语法进入到 Stage 3 阶段后,TypeScript 就会实现它。一方面,让我们可以尽早的使用到最新的语法,帮助它进入到下一个阶段;另一方面,处于 Stage 3 阶段的语法已经比较稳定了,基本不会有语法的变更,这使得我们能够放心的使用它 2.TypeScript 的发展历史 2012-10:微软发布了 TypeScript 第一个版本(0.8),此前已经在微软内部开发了两年。 2014-04:TypeScript 发布了 1.0 版本。 2014-10:Angular 发布了 2.0 版本,它是一个基于 TypeScript 开发的前端框架。 2015-01:ts-loader 发布,webpack 可以编译 TypeScript 文件了。 2015-04:微软发布了 Visual Studio Code,它内置了对 TypeScript 语言的支持,它自身也是用 TypeScript 开发的。 2016-05:@types/react 发布,TypeScript 可以开发 React 应用了。 2016-05:@types/node 发布,TypeScript 可以开发 Node.js 应用了。 2016-09:TypeScript 发布了 2.0 版本。 2018-06:TypeScript 发布了 3.0 版本。 2019-02:TypeScript 宣布由官方团队来维护 typescript-eslint,以支持在 TypeScript 文件中运行 ESLint 检查。 2020-05:Deno 发布了 1.0 版本,它是一个 JavaScript 和 TypeScript 运行时。 2020-08:TypeScript 发布了 4.0 版本。 2020-09:Vue 发布了 3.0 版本,官方支持 TypeScript。
-
缺点
1.有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Class)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念; 2.短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本; 3.集成到构建流程需要一些工作量;ts-loader 4.可能和一些库结合的不是很完美。
4、总结
- TypeScript 是添加了类型系统的 JavaScript,适用于任何规模的项目。
- TypeScript 是一门静态类型、弱类型的语言。
- TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性。
- TypeScript 可以直接运行,最终编译为 JavaScript,然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。
- TypeScript 拥有很多编译选项,类型检查的严格程度由你决定。
- TypeScript 可以和 JavaScript 共存,即JavaScript 项目能够渐进式的迁移到 TypeScript。
- TypeScript 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
- TypeScript 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
- TypeScript 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。
二、安装和运行
1、全局安装 TypeScript
TypeScript 的命令行工具安装方法如下:
npm install -g typescript
以上命令会在全局环境下安装 tsc
命令,安装完成之后,就可以在任何地方执行 tsc
命令了。
2.创建tsconfig.js文件
tsc --init
3.创建一个 TypeScript 文件:
约定使用 TypeScript 编写的文件以 .ts
为后缀。
//test.ts
const hello : string = "Hello World!";
console.log(hello);
4.编译一个 TypeScript 文件:
进入test.ts文件所在目录,执行命令 会生成一个对应的js
tsc test.ts
5.运行一个 TypeScript 文件:
$ node test.js
6.直接运行
安装全局的ts-node模块 不需要转为js文件了
npm install -g ts-node
然后就可以直接执行ts文件了
ts-node test.ts
三、变量声明
-
与js相同,使用var、let或const等
-
声明变量指定类型(任意类型都可),这样的变量赋值时只能使用指定类型的值,以达到强类型语言变量的特点及其优点
const a:number=100
console.log(a)
var b:string="hello"
console.log(b)
let c:boolean=true
console.log(c)
四、基础类型
1、布尔值
是最基础的数据类型,只有简单的true/false两个值 ,使用 boolean
定义布尔值类型:
let isDone: boolean = false;
// 编译通过
// 后面约定,未强调编译错误的代码片段,默认为编译通过
注意,使用构造函数 Boolean
创造的对象不是布尔值:事实上:
let createdByNewBoolean: Boolean = new Boolean(1);
直接调用 Boolean
也可以返回一个 boolean
类型:
let createdByBoolean: boolean = Boolean(1);
在 TypeScript 中,boolean
是 JavaScript 中的基本类型,而 Boolean
是 JavaScript 中的构造函数。
2、数值
和JS一样,TS里的所有数字都是浮点数,类型是 number。 支持2、8、10、16
等各种进制。
let n1: number = 6; //将n1声明为number类型
let n2: number = 0xf00d; // ES6 中的十六进制表示法,会被编译为十进制数字
let n3: number = 0b1010; // ES6 中的二进制表示法,会被编译为十进制数字
let n4: number = 0o744; // ES6 中的八进制表示法,会被编译为十进制数字
let n5: number = NaN;
let n6: number = Infinity; //NaN和Infinity也是属于number类型
3、字符串
用 string
表示文本数据类型。 和JS一样,可以使用双引号( "
)、单引号('
)和反引号(`)表示。
var str="hello" //隐式推论 通过赋初始值 可以推测出是string类型 可省略不写类型
//str=200 会报错 :一个变量声明了类型后就不能改变
// 模板字符串
let myName:string='haha'
let str1: string = `Hello, my name is ${myName}.`;
字符串字面量类型
字符串字面量类型用来约束取值只能是某几个字符串中的一个。
//关键字type :定义一个自定义类型
type mytype="aaa"|"bbb"|"ccc"
var str1:mytype;
str1="aaa" //不报错
// str1="haha" //报错 不能将类型“"haha"”分配给类型“mytype”
//只有值为"aaa" "bbb" "ccc"中的一个才会编译成功
4、数组
有两种方式可以定义数组:
第一种:可以在元素类型后面接上 []
,表示由此类型元素组成的一个数组。
let arr:number[]=[1,2] //定义一个数组是字符串类型的数组
第二种:可以指定数组内有多种类型的值
let arr4:Array<number|string|boolean> =[1,3,"haha",true] //数组的值可以是数字、字符串和布尔
5、元组Tuple
元组类型允许表示一个已知元素数量和类型的数组
,各元素的类型不必相同。
//声明一个包含两个数据(第一个为number类型,第二个为string类型)的元组
let tup:[number,string]
tup=[100,"tuple"] //赋值时:类型和顺序一一对应
//tup=[100,"tuple",4] 报错:源具有 3 个元素,但目标仅允许 2 个。
let tup1:[number,string,boolean]=[3,"lili",true]
let n:number=tup1[0] //取出3 取值同数组通过下标操作
6、枚举
枚举类型用于取值被限定在一定范围内的场景
用enum关键字 声明一个枚举类型 值会自动增长 默认从0开始,可以自己设置
enum data {emailError=4001,pwdError,verifyError=4004}
console.log(data.emailError) //4001
console.log(data["pwdError"]) //4002 自动增长
console.log(data["verifyError"]) //4004 手动设置
7、任意值Any
有时需要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查即静默。 那么我们可以使用 any
类型来标记这些变量。
可以认为,声明一个变量为任意值之后,对它的任何操作,返回的内容类型都是任意值。
let bb:any
bb=100
bb="haha" //赋值都不会报错,因为any可以接收任意值
8、空值Void
表示没有任何类型。 当一个函数没有返回值时,其返回值类型是 void
;
function fn(): void {
console.log("This is my function");
}
声明一个void
类型的变量只能为它赋予undefined
和null
:
let data1: void = undefined;
let data2: void = null;
9、Null 和 Undefined
undefined
和null
两者各自有自己的类型undefined和null
null和undefined是所有类型的子类型
严格模式下undefined不可以赋给任意值,非严格模式下undefined可以赋值给任意类型
10、Never
never
类型表示的是那些永不存在的值的类型。 例如, never
类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型
// 返回never的函数必须存在无法达到的终点 即函数不会正常运行
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
11、Object
object
表示非原始类型,也就是引用类型,是除number
,string
,boolean
,symbol
,null
或undefined
之外的类型,可以使用"对象", "数组对象"、string、number等为其赋值,null和undefined不行的。 之所以Object变量可以接收任何对象,是因为Object是所有类的父类
在TS中,null是所有引用类型的子类,用object定义的变量都可以赋值为null。
let obj:object=[1,2]
let obj2:object={age:21}
//let obj3:object=200 不能将类型“number”分配给类型“object”
console.log(typeof obj) //object
console.log(typeof null) //object 因为是node在跑js代码 所以还是object
12、类型别名与联合类型
用关键字type 自定义一个联合类型 comp就是别名
type comp=string|number|boolean
let com1:comp
com1=1
com1="haha"
com1=true
数组联合类型的两种写法:
type mytype=number|string
let arr1:mytype2[]=[1,2,"3"]
let aarr1:Array<number|string>=[1,2,"3"]
13、类型推论
没有声明类型的变量,但被赋值一次后,就根据赋的值确定变量的类型,之后再次被赋值时,不可改变赋值的类型。
let num = 100;//确定了num的类型为number
num = "fds"; //编译报错,因为num的类型为number,不可以修改为string类型
五、类型断言
类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误。
类型断言有两种形式:“尖括号”语法 和 as
语法
1、“尖括号”语法:<类型>变量
<类型>变量名:表示断言变量是尖括号里的类型
let someValue: any = "this is a string";
//someValue ==>是个any类型
//断言someValue是个string类型,那么.length一定是个number类型
let strLength: number = (<string>someValue).length;
2、as语法:变量 as 类型
let someValue: any = "this is a string";
//someValue.length ==>是个any类型
//(someValue as string).length ==>是个number类型
let strLength: number = (someValue as string).length; //string的length一定是number
注:类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的。如:
function fn(): any { return "hello" } type mytype = number | string let a: mytype = fn() let b: number = 100 //let a: mytype = "hello" 不能把它写死成字符串 用个返回任意值的函数fn //b = a 编译报错 string不能赋值给number b = a as number //假装fn()小括号的结果是number 赋值给number就不会错