TypeScript学习笔记
TypeScript
是JavaScript的超集且支持ES6标准,由微软开发。
TypeScript是设计用来开发大型应用的,可以编译成js并运行在浏览器上。
语言特性
ts扩展的内容
TypeScript是js的扩展,扩展的内容如下:
- 类型批注和编译时类型检查
- 类型推断
- 类型擦除
- 接口
- 枚举
- Mixin
- 泛型编程
- 名字空间
- 元组
- await
以及从ECMA2015一直了如下内容:
- 类
- 模块
- lambda函数的箭头语法
- 可选参数和默认参数
ts和js的区别
ts是js的超集,它扩展了js的语法。
ts通过类型注解提供编译时的静态类型检查。
ts可以处理已有的js代码并只对其中的ts代码进行编译。
实例
1 | const str : string = "this is a string." |
安装
npm安装
1 | # 使用npm全局安装ts |
编译
将ts编译为js代码:
1 | # ts文件扩展名为.ts |
运行
ts已经被编译成了js文件,使用node命令运行js。
1 | node demo.js |
基本语法
TypeScript程序由模块、函数、变量、语句和表达式以及注释组成。
编译参数
tsc常用编译参数:
1 | # 显示帮助信息 |
保留关键字
- 保留关键字
1 | break as catch switch |
- 空白和换行
ts会忽略空格、tab和换行。
ts区别大小写
ts中分号可选
建议使用分号。
- 注释
建议每段代码都写注释以提高程序可读性。
编译器会忽略注释。
ts支持的注释类型:
1 | // 单行注释 |
面向对象
TypeScript是面向对象的编程语言。
面向对象有两个重要概念:对象和类。
- 类:类是一个模板,描述一类对象的状态和行为。
- 对象:对象是类的实例,有状态和行为。
- 方法:方法是类的操作的实现步骤。
实例:
1 | // 定义一个类 |
现在将这个ts编译为js,编译之后的js代码为:
1 | var Person = /** @class */ (function() { |
基本数据类型
any
关键字声明任意类型。
TypeScript针对类型不明确时提供了any类型。
三种用途:
- 变量的值会动态改变。
1 | let x: any = 1; |
- 改写原有代码的时候,使用any类型可以允许在编译的时候可选择的包含或者移除类型检查。
1 | let x: any = 4; |
- 定义存储各种类型数据的数组的时候使用any。
1 | let arr: any[] = [1,'a string',true]; |
number
关键字声明数字类型,采用双精度64位浮点数,可以用来表示整数和分数。
1 | // 声明并赋值一个二进制数 |
string
关键字声明字符串类型,使用单引号或者双引号表示字符串,反引号`定义多行文本和内嵌表达式。
1 | let name: string = 'mason'; |
boolean
关键字声明布尔型,两个值为true
和false
。
1 | let fake: boolean = false; |
number[]
来声明数组类型。
1 | // 在元素类型后面加上[]即可声明数组 |
- 元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
1 | // 声明元组,元组各个位置上的数据类型要相符,下面尝试赋值 |
enum
关键字,枚举类型用于定义数值集合。
1 | enum Color {Red, Green, Blue}; |
void
关键字用于标识方法没有返回值。
1 | function func(): void { |
null
关键字标识对象值缺失。
js中的null表示什么都没有。
null是一个只有一个值的特殊类型,表示一个空对象引用。typeof null
得到 object
。
undefined
关键字用于初始化变量为一个未定义的值。
js中的undefined是一个没有设置值的变量。
never
是其他类型的子类型,代表不会出现的值。
声明为never类型的变量只能被never类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)。
1 | let x: never; |
JavaScript是弱类型语言故而没有整数类型,TypeScript是强类型语言但是只能用number关键字声明数字并且不区分整数和浮点数故而也没有整数类型。
可以使用|来支持多种类型
1 | let x: number | null | undefined; |
tips:
如果某个属性的值是计算出来的,则它后面的一个变量必须初始化,否则编译报错。
变量声明
变量用于引用内存地址。
变量可以看做是存储数据的容器。
ts变量命名规则:变量名由数字、字母和 _
以及 $
构成,且不能以数字开头。
变量使用前必须声明。
各种声明方式:
1 | // 声明变量类型并初始化 |
实例:
1 | var uname:string = "mason"; |
变量名不能使用 name
,会与 windows.name
冲突。
编译为js:
1 | var uname = "mason"; |
ts是强类型语言,声明类型和字面量类型不同则编译错误:
1 | // 声明为number类型却复制为string类型,编译错误 |
类型断言
类型断言(Type Assertion)可以用于手动指定一个值的类型,也就是将一个变量改变为另一个类型。
1 | // 方法一 |
实例:
1 | // 声明变量为string类型 |
关于断言:
- 当A类型是B类型的子集或者A类型是B类型的父集,A类型都能被成功断言为A类型,这个是为了安全考虑,若强行断言则可以使用
any
。 - 类型断言不是类型转换,类型转换是在程序运行时完成的,而类型断言则是纯粹的编译时语法。
类型推断
当没有给出类型的时候,tsc会利用类型推断来推断类型。
如果缺乏声明而导致不能推断出类型,则默认其类型为 any
。
1 | // 注意这里不是js声明,这里是ts声明变量,却没有声明类型,类型推断为number |
变量作用域
ts中的变量作用域:
- 全局作用域:全局变量定义在程序结构的外部,在任何位置都可以调用。
- 类作用域:也称之为字段,类变量声明在一个类里面且在类的方法外面。可以使用类的对象访问。类变量可以使静态的,可以通过类名直接访问。
- 局部作用域:局部变量,生命在一个代码块中,作用域就在这个代码块。
实例:
1 | // 全局变量 |
这是上面的四种变量对应的访问方式:
1 | // 全局变量 |
更多参考:https://ts.xcatliu.com/basics/type-assertion.html
运算符
ts有以下几种运算符:
- 算术运算符
- 逻辑运算符
- 关系运算符
- 按位运算符
- 赋值运算符
- 三元/条件运算符
- 字符串运算符
- 类型运算符
算数运算符
有 +
, -
, *
, /
, %
, ++
, --
,其中 ++
, --
还有写在值之前和之后之分。
比如 ++
,写在值之前是先自增再用,写在值之后是先用再自增。
关系运算符
关系运算法计算表达式是 true
还是 false
。
关系运算符有这些: ==
, !=
, >
, <
, >=
, <=
。
逻辑运算符
逻辑运算符用于测定变量或者值之间的逻辑。
逻辑运算符有这些: &&
, ||
, !
。
其中 &&
和 ||
可以短路: &&
左边为 true
则返回右边的, ||
之前的变量或值为 true
则返回 &&
之前的变量或值。
位运算符
位运算符是对变量按位进行二进制操作(有一元操作符和二元操作符)。
位运算符有这些:
&
:按位与处理两个长度相同的二进制数。|
:按位或处理两个长度相同的二进制数。~
:取反,取反是一元运算符,对一个二进制数的每一位执行逻辑反操作。^
:按位异或运算,对等长二进制模式按位或二进制数的每一位执行逻辑异按位或操作。操作的结果是如果某位不同则该位为 1,否则该位为 0。<<
:把 << 左边的运算数的各二进位全部左移若干位,由 << 右边的数指定移动的位数,高位丢弃,低位补 0。>>
:把 >> 左边的运算数的各二进位全部右移若干位,>> 右边的数指定移动的位数。>>>
:无符号右移,与有符号右移位类似,除了左边一律使用0 补位。
1 |
|
赋值运算符
赋值运算符有: =
, +=
, -=
, *=
, /=
。
三元运算符
语法: condition ? expression1 : expression2
三元运算符 ?
有三个操作数,第一个操作数为 true
则返回第二个操作数,为 false
则返回第三个操作数。
实例:
1 | var num: number = -1; |
类型运算符
- typeof:一元运算符,返回数据类型。
1 | var num: number = 12; |
- instanceof:判断对象是否是指定类型。
其他运算符
符号运算符:用于取负值。
字符串运算符(链接运算符):用于拼接两个字符串。
条件语句
条件语句用于基于不同的条件执行不同的操作。
if语句
if语句由布尔表达式和多个语句组成。
语法:
1 | // type1 |
switch…case语句
switch...case
语句允许测试一个变量等于多个值时的情况,每一个值都是一个case,被测变量以此检查case。
switch…case语句规则:
- expression是一个常量表达式(整形或者枚举型)。
- case可以与多个,后面跟一个值和冒号。
- expression和exp必须要是相同的数据类型。
- expression和exp相等时执行case后面的语句,直到遇到
break;
跳出switch。 - 如果语句不包含break则顺序往下面的case执行直到遇到break。
- switch可以有多个default,放置在switch最后面。
语法:
1 | switch(expression) { |
循环
for循环
1 | for (init; condition; inc) { |
下面是 for 循环的控制流程解析:
- init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
- 接下来,会判断 condition。如果为 true,则执行循环主体。如果为 false,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
- 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
- 条件再次被判断。如果为 true,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为 false 时,for 循环终止。
在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
condition 可以是任意的表达式,当条件为 true 时执行循环,当条件为 false 时,退出循环。
实例:计算5的阶乘5!
1 | var result: number = 1; |
for…in循环
for…in循环用于一组值的集合或列表进行迭代输出。
1 | for (var val in list) { |
val
为string或者any。
实例:
1 | var num: any; |
for…of, forEach, every, some
for...of
是es6中引入的代替for...in
和forEach()
,用于创建一个循环来迭代可迭代的对象,支持新的迭代协议。
可以使用for…of遍历数组、字符串、映射(maps)、集合(sets)等等可迭代的数据结构。
实例:
1 | let someArray = [1, "string", false]; |
forEach
, every
和 some
是js中的循环语法,ts也支持这几种循环。
forEach
1 | let list = [1,2,3]; |
every
1 | let list = [4, 5, 6]; |
while
1 | while (condition) { |
do…while
do...while
中的statement代码至少被执行一次。
1 | do { |
break
用法:
- 在循环内使用的时候会终止并跳出当前循环。
- switch…case中使用跳出switch。
语法:
1 | break; |
continue
continue跳过当前循环开始下一个循环。
语法:
1 | continue; |
无限循环
for和while都可以创建无限循环(死循环)。
1 | for (;;) { |
函数
函数是一组ts语句。
函数声明包括函数的名称、返回值类型和参数。
函数的定义
1 | // 一个名为func的函数 |
调用函数
调用上面的 func
函数。
1 | func(); |
函数返回值
有时我们希望函数能返回一个值用于调用它的地方,通过return语句可以返回一个值并停止函数的执行。
1 | function func(): string { |
一个函数只能有一个return,返回值类型要和函数定义的返回值类型一样。
带参数的函数
1 | function func(param1: number, param2: string,param3: boolean) { |
可选参数和默认参数
- 可选参数
使用问号 ?
表示可选参数,且只能放在后面。
1 | // 这里第三个参数是可选的 |
- 默认参数
1 | 这里给第三个参数默认值`true` |
剩余参数
用于不知道向函数传多少个参数的时候。
使用 ...restOfName
表示剩余参数,是一个数组。
1 | function buildName(firstName: string, ...restOfName: string[]) { |
匿名函数
匿名函数就是没有函数名的函数。
匿名函数用的时候动态声明。
也可以将匿名函数赋值给变量,这种就叫做函数表达式。
1 | let func = function () { //statement } |
匿名函数立即执行
1 | (function () { |
构造函数
ts也支持js的 new Function()
来定义函数。
1 | var res = new Function ([arg1[, arg2[, ...argN]],] functionBody); |
实例:
1 | var myFunction = new Function("a", "b", "return a * b"); |
递归函数
递归函数就是在函数内部调用自身。
1 | function factorial(number) { |
lambda函数
lambda
函数就是箭头函数。
单个参数 ()
可选,单行函数体则 {}
也是可选的,如果没有参数则要保留一堆括号 ()
。
语法:
1 | // 单行 |
实例:
1 | var foo = (x: number) => x++; |
上面的代码等同于:
1 | var foo = function(x) { |
函数重载
重载就是调用的函数相同但是参数不同,返回值类型可以不同。
每个重载的方法都要有独一无二的参数类型列表。
重载的例子:
1 | // 参数类型不同 |
如果参数类型不同,则参数类型要设置为 any
。
参数数量不同,要将不同的参数设置为可选。
实例:参数数量和类型不同
1 | function disp(s1:string):void; |
Number对象
ts也支持Number对象,Number对象是原始数据类型的包装对象。
1 | var num = new Number(1); |
Number对象属性
MAX_VALUE
:可表示的最大的数字。MIN_VALUE
:可表示的最小的数字。NaN
:not a number。POSITIVE_INFINITY
:正无穷。NEGATIVE_INFINITY
:负无穷。prototype
:Number 对象的静态属性。使您有能力向对象添加属性和方法。constructor
:返回对创建此对象的Number函数的引用。
实例:
1 | console.log("最大值为: " + Number.MAX_VALUE); |
输出:
1 |
|
Number对象方法
toExponential()
:将数字转化为指数计数法。toFixed()
:将数字指定小数点位数并转化为字符串。toLocaleString()
:把数字转换为字符串,使用本地数字格式顺序。toPrecision()
:把数字格式化为指定的长度。toString()
:把数字转换为字符串,使用指定的基数。数字的基数是2 ~ 36之间的整数。若省略该参数,则使用基数10。valueOf()
:返回一个Number对象的原始数字值。
String对象
String对象用于处理字符串。
1 | var str = new String('this is a string.'); |
String对象属性
constructor
:对创建该对象的构造函数的引用。length
:返回字符串的长度。prototype
:可以向对象添加属性和方法。
String对象方法
charAt()
:返回在指定位置的字符。charCodeAt()
:返回在指定的位置的字符的Unicode编码。concat()
:连接两个或更多字符串,并返回新的字符串。indexOf()
:返回某个指定的字符串值在字符串中首次出现的位置。lastIndexOf()
:从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置。localeCompare()
:用本地特定的顺序来比较两个字符串。match()
:查找找到一个或多个正则表达式的匹配。replace()
:替换与正则表达式匹配的子串。search()
:检索与正则表达式相匹配的值。slice()
:提取字符串的片断,并在新的字符串中返回被提取的部分。split()
:把字符串分割为子字符串数组。substr()
:从起始索引号提取字符串中指定数目的字符。substring()
:提取字符串中两个指定的索引号之间的字符。toLocaleLowerCase()
:根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射。toLocaleUpperCase()
:据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射。toLowerCase()
:把字符串转换为小写。toString()
:返回字符串。toUpperCase()
:把字符串转换为大写。valueOf()
:返回指定字符串对象的原始值。
Array对象
ts如何声明数组:
1 | // 声明一个变量为site的字符串类型的数组 |
或者声明并初始化:
1 | var sites: string[] = ['baidu','google','amazon']; |
如果数组声明时未设置类型,则会被认为是 any
类型,在初始化时根据第一个元素的类型来推断数组的类型。
访问数组:
1 | var sites: string[]; |
使用Array对象创建数组
Array创建对象的时候可以接受两种值。
- 数组的长度。
- 初始化数组的元素。
1 | var sites: string[] = new Array(3); |
或者:
1 | var sites: string[] = new Array('google','baidu','amazon'); |
数组结构
也可以将数组元素赋值给变量:
1 | var arr: number[] = [1,2]; |
数组迭代
1 | var nums:number[] = [1,2,3,4]; |
多维数组
可以将一个数组作为另一个数组的元素,这就是多维数组。
二维数组定义:
1 | var arr: number[][] = [[1,2,3],[4,5,6]]; |
数组在函数中的使用
- 作为参数传递到函数进行操作。
- 作为函数的返回值。
1 | function returnArray():string[] { |
数组方法
concat()
:连接多个数组。
1 | var alpha = ['a','b','c']; |
every()
:检测数组元素是否都符合条件。
1 | // 声明并初始化待检测数组 |
filter()
:检测数值元素并返回符合条件的数组。
1 | // 声明并初始化待检测数组 |
forEach()
:为数组的每一个元素都执行一次回调函数。
1 | let nums = [1,2,3]; |
indexOf()
:返回一个元素所在的索引位置,找不到则返回-1.
1 | console.log([1,2,3,4].indexOf(2)); |
join()
:将数组的所有元素都放入一个字符串。
1 | var arr = ['i','have','a','pen']; |
lastIndexOf()
:返回指定字符串最后出现的位置(会从最后面向前搜索)。
1 | var index = [12, 5, 8, 130, 44].lastIndexOf(8); |
map()
:用指定函数梳理数组中每一个元素并返回处理后的数组。
1 | var numbers = [1, 4, 9]; |
pop()
:删除数组的最后一个元素并返回删除的元素。
1 | var numbers = [1, 4, 9]; |
push()
:向数组添加元素并返回新数组的长度。
1 | var numbers = [1, 4, 9]; |
reduce()
:从左到右将数组元素计算为一个值。
1 | var arr = [1,2,3,4]; |
reduceRight()
:从右到左将数组元素计算为一个值。reverse()
:反转数组的元素顺序。
1 | var arr = [1,2,3,4]; |
shift()
:删除并返回数组的第一个元素。
1 | var arr = [1,2,3,4].shift(); |
slice()
:选取数组的一部分并返回一个新数组。
1 | var arr = ["orange", "mango", "banana", "sugar", "tea"]; |
some()
:检测数组中是否存在符合条件的元素并返回布尔值。
1 | function isBigEnough(element, index, array) { |
sort()
:对数组元素进行排序。
1 | var arr = new Array("orange", "mango", "banana", "sugar"); |
splice()
:从数组中添加或者删除元素。
1 | var arr = ["orange", "mango", "banana", "sugar", "tea"]; |
toString()
:把数组转换为字符串,并返回结果。
1 | var arr = new Array("orange", "mango", "banana", "sugar"); |
unshift()
:向数组的开头添加一个或更多元素,并返回新的长度。
1 | var arr = new Array("orange", "mango", "banana", "sugar"); |
Map对象
Map对象是es6引入的,用于保存键值对并且能记住键的原始插入顺序。
创建Map
1 | // 声明 |
Map属性与方法
map.clear()
:删除map对象的所有键值对。map.set()
:设置键值对,返回该对象。map.get()
:读取键对应的值,不存在则返回undefined。map.has()
:查询map对象中是否存在某个键对应的值,返回布尔值。map.delete()
:删除map对象中的键值对,成功返回true,失败返回false。map.size
:返回map对象的长度,也就是键值对的个数。map.keys()
:返回一个Iterator对象(迭代器),包含了map对象中每个元素的键。map.values()
:返回一个Iterator对象,包含了map对象中每个元素的值。
实例:
1 | let nameSiteMapping = new Map(); |
使用es6编译:
1 | tsc --target es6 test.ts |
运行结果:
1 | 2 |
迭代Map
使用for…of迭代:
1 | let nameSiteMapping = new Map(); |
使用es6编译:
1 | tsc --target es6 test.ts |
执行结果:
1 |
|
元组
数组中存储的元素类型都是一样的,如果要在数组中存储不同类型的元素则用元组。
定义元组
1 | var mytuple = [val1,val2,val3...]; |
实例:
1 | var mytuple = [1,'asd',false]; |
访问元组
1 | mytuple[index]; |
元组的运算
push()
:向元组最后面添加元素。pop()
:删除元组最后面一个元素并返回被删除的元素。
更新元组
可以改变元组元素。
结构元组
1 | var a =[10,"Runoob"] |
联合类型
可以通过使用管道符 |
将变量设置为多种类型。
1 | type1 | type2 | type3 |
实例:
1 | var val: string | number; |
将联合类型作为函数的参数使用:
1 | function disp(name:string|string[]) { |
联合类型数组
将数组声明为联合类型:
1 | var arr:number[]|string[]; |
接口
接口的定义
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
ts接口的定义:
1 | interface interface_name { |
实例:
1 | // 定义了接口IPerson |
接口不能编译为js。
联合类型和接口
在接口中使用联合类型:
1 | interface RunOptions { |
接口和数组
接口中可以将数组的index和value设置为不同类型。
接口的继承
接口的继承就是一个接口可以继承多个接口。
使用关键字 extends
。
使用:
1 | interface_A extends interface_B |
实例:单继承
1 | interface Person { |
实例:多继承
1 | interface IParent1 { |
类
类的定义
ts是面向对象的js。
类描述了所创建对象的共同的属性和方法。
ts支持面向对象的所有特性:类、接口等。
ts类的定义:
1 | class class_name { |
实例:
1 | class Person { |
创建类的数据成员
1 | class Car { |
实例化
使用 new
来实例化类的对象。
1 | var object_name = new class_name([ arguments ]); |
实例:
1 | class Car { |
类的继承
使用关键字 extends
继承父类,只能继承一个父类。
1 | class class_A extends class_B |
实例:
1 | class Shape { |
ts中一个类只能继承一个父类,但是支持多重继承。
1 | class Root { |
继承类的方法重写
子类继承了父类以后,子类可以对父类的方法重写。
super
关键字是对父类的引用,可以使用 super
引用父类的属性和方法。
1 | class PrinterClass { |
static关键字
static
关键字用于定义类的数据成员(属性和方法)为静态,静态成员可以通过类名调用。
1 | class StaticMem { |
instanceof运算符
用于判断对象是否是指定的类型。
1 | class Person{ } |
访问控制修饰符
ts中可以使用访问控制修饰符来保护对类、变量、方法和构造方法的访问。
public
:默认值,共有,在任何地方都可以被访问。protected
:受保护的,只可以被自己和子类和父类访问。private
:私有的,只能被其定义所在的类访问。
1 | class Encapsulate { |
类和接口
类可以用 implements
关键字实现接口并将 interest
字段作为类的属性使用。
1 | interface ILoan { |
对象
对象的定义
对象是键值对的集合。
1 | var object_name = { |
1 | var sites = { |
类型模板
js对象添加方法:
1 | var sites = { |
ts中的对象必须是特定类型的实例:
1 | var sites = { |
鸭子类型
鸭子类型是动态类型的一种风格,是多态的一种形式。
1 | interface IPoint { |
命名空间
命名空间是用来解决命名重名的问题。
命名空间定义了标识符的可见范围。
ts中使用 namespace
来定义命名空间。
定义命名空间:
1 | namespace SomeNameSpaceName { |
使用 export
关键字让外部可以调用 SomeNameSpaceName
中的类和接口。
在另一个命名空间调用:
1 | SomeNameSpaceName.SomeClassName; |
如果一个命名空间在一个单独的ts文件中,使用 ///
引用它:
1 | /// <reference path = "SomeFileName.ts" /> |
嵌套命名空间
可以将一个命名空间定义在另一个命名空间里面, 成员的访问使用点号。
模块
TypeScript 模块的设计理念是可以更换的组织代码。
模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。
两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。
模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。 大家最熟知的JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js。
此外还有有 SystemJs 和 Webpack。
使用 export
关键字导出模块:
1 | // 文件名 : SomeInterface.ts |
使用 import
关键字导入上面的模块:
1 | import someInterfaceRef = require("./SomeInterface"); |
声明文件
声明
TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。
实例:ts获取id
在js中:
1 | // js中使用jquery获取id |
在ts中:
1 | // 用declare关键字定义它的类型 |
上面代码的编译结果是:
1 | jQuery('#foo'); |
声明文件
声明文件以 .d.ts
结尾。
声明文件或者模块:
1 | declare module Module_Name { |
ts引入声明文件:
1 | /// <reference path = " runoob.d.ts" /> |
实例:
这是一个第三方库文件:CalcThirdPartyJsLib.js
1 | var Runoob; |
在ts中引用上面的文件,在声明文件中要这样写:
1 | declare module Runoob { |
把声明文件加入到ts中:
1 | /// <reference path = "Calc.d.ts" /> |
然后编译ts文件。
然后在html中引入编译后的文件以及第三方库文件:
1 |
|
总结
接口、类、对象、命名空间、模块以及声明文件需要再配合其他资料理解一下。