<>前言
TypeScript是JavaScript的、带有类型的超集,并且能够编译为普通的JavaScript。它是一种建立在JavaScript上的编程语言,也是一种工具。它是一个强大的编译器,你可以在代码上运行,将TypeScript编译为JavaScript。
它为JavaScript添加新功能和优势。但是,TypeScript在JavaScript环境无法运行,浏览器无法执行类型脚本。
优点:类型检查;代码补全;易于维护;入门简单。它使编写干净的代码变得非常容易。
TypeScript添加类型和数据对类型非常重要,我们必须更明确地了解事情的运作方式,可以避免很多使用类型的意外和不必要的错误。TypeScript是可配置的。
TypeScript可以在开发过程中帮助我们进行检查,允许我们更早地修复错误。TypeScript只能在开发期间获得支持,不在运行时,因为这些类型脚本功能和检查没有内置到JavaScript引擎中,这样的逻辑就不能在浏览器中执行,它只能在开发期间执行。
<>一、安装TypeScript
首先,确保你的电脑安装了Node.js。
输入命令npm install -g
typescript;把TypeScript编译器安装到全局,这样,所有的typescript项目都可以使用它。安装完成,我们可以使用 tsc 命令来执行
TypeScript的相关代码,输入tsc - v命令来查看版本号,看到TypeScript的版本号说明安装成功了。
<>二、基本使用
新建一个LearningTypeScript文件夹,用VSCode打开。在这个文件夹中新建一个demo01.ts文件。里面写一点内容,如下所示。
在终端输入tsc demo01.ts,TypeScript编译器就可以把ts文件编译成js文件了。
可以看到在文件夹中生成了一个新的demo01.js文件。
运行一下,输入:node demo01.js,可以看到输出了数字13。
<>三、配置编译版本
那么,JavaScript的版本这么多,tsc如何知道应该编译成哪种版本呢?
tsc默认会编译成ES3版本。我们试一下在demo01.ts文件中加一个async异步函数,它是ES1017版本的,应该如何编译呢?
我们可以在文件夹中新建一个tsconfig.json配置文件,通过compilerOptions属性来配置tsc编译器,target⽤于指定要编译成的版本,这里指定ES2017。
现在,再次运行tsc,后面不需要加文件名了。因为有了tsconfig.json文件之后,这个文件夹会自动成为typescript的项目,tsc会自动找到ts文件并进行编译。如果制定了文件名,那么这个配置文件的配置就会被忽略了。
打开js文件,发现和ts文件的async函数一样。
<>四、相关特性
<>1.基本类型
给变量定义类型有两种方式,一种是隐式的,一种是显式的。
隐式类型由typescript根据变量的值来推断类型。代码写法与js一样,但是,它后面不能用其他类型的值给它重新赋值。比如定义一个let a = 10,a
= ‘hello’;这样编译器就会报错,提示“hello字符串不能赋值给数字类型”!
let a = 10; a = 'hello';
基本类型与javascript一样:boolean number string undefined null
。显示类型的定义,就跟之前运行的ts代码示例一样,用冒号加类型来显示地规定这个变量是什么类型的。
// : boolean 表示是布尔类型的 let b: boolean = true; // : number 表示是数字类型的 let c: number
= 22; // 字符串类型 let s: string = 'john'; // undefined let u: undefined = undefined
; // null let n: null = null;
如果想让一个变量可以是任何类型的,那么可以把它的类型定义为any。声明为 any 的变量可以赋予任意类型的值。
例如:给a一个数字类型的值,再改成字符串,这时候就不报错啦。
let a:any = 10; a = "hello"
<>2.函数
类型也可以用在函数的参数和返回值中。
比如下面的例子中:定义一个加法函数,接收类型为number的两个参数a、b;返回值的类型也是number,返回值的类型定义在参数列表的小括号后面;再后面才是函数体。
//类型也可以用在函数的参数和返回值中 //
比如:定义一个加法函数,接收类型为number的参数n1、n2;返回值的类型也是number,返回值的类型定义在参数列表的小括号后面;再后面才是函数体。 //
实例中定义了函数 add(),返回值的类型为 number。 // add() 函数中定义了两个 number
类型的参数,参数之间用,分隔,函数内将两个参数相加并返回。 function add(n1: number, n2: number): number { //
通过使用 return 语句就可以实现返回值,在使用return语句时,函数会停止执行,并返回指定的值。 // 返回a+b return n1 + n2; }
// 如果函数没有返回值,可以使用void类型表示函数没有返回值。如下所示: // function
add(n1:number,n2:number):void{ // console.log(n1+n2) // } // 调用函数 //
不能使用字符串变量来接收函数的返回值,会报错。比如:let res:String = add(1,2);提示“number类型不能赋值给string类型!”
// 不能给函数传递字符串。比如:add("1",2);那么编译器会提示“字符串1不能传给number类型的函数!” //
调用函数时,必须传递与参数列表一样的参数,不像js,可以不传或只传一个参数。比如:add(1);就会提示“没有给n2传值!” // 在 TypeScript
函数里,如果我们定义了参数,则我们必须传入这些参数。除非将这些参数设置为可选,可选参数使用问号标识 ?。 add(1, 2);
<>3.组合类型
如果一个变量可以有多个类型,但是又不想使用any破坏类型检查,就可以使用组合类型。
* 或 |
比如:一个变量p既可以是数字类型也可以是字符串类型。
let p:number | string = 10; p = "hello typescript";
不过,代码这样看起来不大方便。并且这个组合类型只能给p使用。如果有别的变量也是数字或字符串类型,还要重复定义。
要解决这个问题,可以使用type关键字给这个组合类型起一个别名,让代码更易读,也方便变量使用。
例子如下:
// 定义一个type名为NumStr。定义了一个number | string的联合类型变量,因此给变量赋值数值或字符串都是可以的。 type NumStr
= number | string; // p变量定义一个数字 let p:NumStr = 10; p = "hello typescript"; //
q变量定义一个字符串值 let q:NumStr = "hi"; // 组合类型也可以直接使用字面值来定义,这样,就规定了一个变量的取值范围。 //
比如:想让字符串类型的变量只能去on或者off两者之一;那么就可以这么定义,在变量o后面直接使用on off let o: "on" | "off" =
"on"; // 可以给它赋值off o = "off"; //
但是,不能给它赋值除了on、off之外的值,会报错,提示"hah不能赋值给用on或off定义的类型里面!" // o = "hah";
与 &
<>4.对象类型
TypeScript 中,使用interfaces接口,接口是用来规范一个对象里应该都有哪些属性,包括它的名字和它的类型。接口一般首字母大写。
约定俗成:接口的命名一般以大写字母I开头
// 定义一个接口IPerson 接口首字母要大写 interface IPerson { // 接口里面有属性和类型;每个属性后面用分号分隔 name:
string; age:number; hobby:string; } // 根据接口IPerson定义对象,对象实现了接口IPerson的属性和方法。 //
对象里面只能包括接口里定义的属性。对象里面不能多也不能少定义属性,会提示错误信息; let jisoo:IPerson = { name:"jisoo",
age:25, hobby:"sing", }
对象与接口定义的属性类型要对应。
IPerson接口中定义的name是string类型的,对象中如果把name赋值为number类型,就会报错。
定义的变量⽐接⼝多了或者少了⼀些属性都是不允许的。
接口中定义了属性,定义空对象也会报错:
可选属性:有时我们希望不要完全匹配接口中的所有属性,那么可以用可选属性,表示该属性可以不存在。
// 带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个? interface IPerson1 { name: string;
hobby:string; // age为可选属性 age?: number; } let James: IPerson1 = { name: 'James',
hobby:"跑步", };
<>5.数组类型
给数组规定类型,可以保证里面的元素都是同一个类型,以防在统一处理数组元素时,混进来其他类型的元素,导致异常。或者防止意外给数组元素赋了其他类型的值。
要定义数组类型的方法有如下两种:
第一种,可以在类型后面加一对空的方括号 [],表示由此类型元素组成的一个数组;
第二种方式是使用数组泛型,Array<元素类型>。
// 定义一个number类型的数组 // 第一种,可以在类型后面加一对空的方括号 [],表示由此类型元素组成的一个数组 let arr1: number[]
= [1, 2, 3]; // 第二种方式是使用数组泛型,Array<元素类型>。 // 泛型属于面向对象语言中比较高级的特性。
应用在数组身上,同样可以用来规定数组中元素的类型。 let arr2: Array<number> = [1, 2, 3];
<>6.元组tuple
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
// TypeScript中有一个元组tuple。它是一个有限元素数量的数组(固定的数组),并且长度也是固定的。但是,每个元素需要分别指定是什么类型。 //
比如:这里有一个三元组就是这个数组中有三个元素。规定第一个元素是number类型,第二个元素是string类型,第三个元素是boolean类型。 //
声明一个元组并初始化 let mytup:[number,string,boolean] = [1,"joy",true];
访问元组:元组中元素使用索引来访问,第一个元素的索引值为 0,第二个为 1,以此类推第 n 个为 n-1。
元组运算:我们可以使用以下两个函数向元组添加新元素或者删除元素。
* push() 向元组添加元素,添加在最后面。
* pop() 从元组中移除元素(最后一个),并返回移除的元素。
<>7.接口继承
利用extends实现接口继承。
如下所示:接口IChild继承接口IPerson,那么IChild就继承了IPerson的全部属性,那么IChild一共就有4个属性了。
也可以实现继承多个接口:
如下所示,接口IC继承了接口IA和IB,那么IC就会包含IA和IB的所有属性。
<>8.接口定义不确定的属性
接口定义了不确定的属性,那么根据接口定义的对象就可以写任意的属性和值。
<>9.接口实现implements
实现接口的类必须要全部实现接口中的所有属性和方法(可选属性可不写)