TypeScript系列文章导航
TypeScript是以JavaScript为基础构建的语言,是JS的一个超集,拓展了JS,添加了类型。
也因此,TS不能被JS解析器直接运行,需要经过编译,将TS变成为JS。就好比React中的JSX语法,需要被babel
来编译,变成JS。
TS的安装命令如下:
npm i -g typescript
创建一个TS文件,例如:
通过tsc命令对TS文件进行编译:
tsc hello.ts
接下来就可以来学习下TS相关的语法和知识了。
TS指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明。
语法如下:
let 变量: 类型;
let 变量: 类型 = 值;
function fun(参数: 类型, 参数: 类型): 类型 {
...
}
案例1:变量的声明和赋值
// 声明一个变量a,同时指定它的类型是number
let a: number
// a的类型是number,那么在以后的使用过程中a的值只能是数字。
a = 10
// 因此下面这种写法会报错
// a = 'hello'
// 声明一个变量b,类型是string,并且可以直接赋值
// 如果变量的声明和赋值是同时进行的,TS可以自动对变量进行类型检测。
let b: string = 'hello'
// 可以直接改成
// let b = 'hello',若此时写出b = false ,依旧会报错,
// 因为TS进行类型检测,发现b的类型是string,那么就不能更改值为其他类型
案例2:函数中类型的声明
先来看下普通的JS写法:
function sum(a, b) {
return a + b
}
console.log(sum(123, 456))// 输出结果为579
console.log(sum(123, '456'))// 输出结果为123456
可以发现,这个函数的本意是两个整数求和,但是只要我传入的其中一个参数为string
类型,那么结果就成了字符串的拼接。
那么TS的写法如下:
function sum(a: number, b: number) {
return a + b
}
console.log(sum(123, 456))
// 这里代码就直接报错了,提示string类型不能转化为number
// console.log(sum(123, '456'))
类型 | 例子 | 描述 |
---|---|---|
number | 1,3,-20 |
任意数字 |
string | 'hello' |
任意字符串 |
boolean | true /false |
布尔值false 或者true |
字面量 | 其本身 | 限制变量的值就是该字面量的值 |
any | * |
任意类型 |
unknown | * |
类型安全的any |
void | 空值或者undefined |
没有值或者undefined |
never | 没有值 | 不能是任何值 |
object | {name:'hello'} |
任意的JS对象 |
array | [1,2,3] |
任意JS数组 |
tuple | [4,5] |
元素,固定长度的数组 |
enum | enum{A,B} |
枚举 |
// 使用字面量来进行类型声明
let a: 10
// a = 20 报错,因为此时的a的值被限定为10.
// 也可以添加 | ,下方表示b的值只能是male或者female。
let b: 'male' | 'female'
b = 'male'
// 一般都声明其类型,也就是联合类型,如
let c: boolean | string
c = false
c = 'hello'
// any 表示这个变量可以是任意的类型,但是会有个问题,此时相当于关闭了TS的类型检测
let a: any
a = 1
a = 'hello'
a = false
// 如果声明变量的时候不指定类型,那么TS解析器会自动判断变量的类型是any(隐式any)
let b
b = 1
b = false
let c: string
// any类型的变量可以赋值给任意变量
c = b
// unknown表示为未知类型,实际上是一个类型安全的any
let aa: unknown
aa = 10
aa = false
let bb: string
// bb = aa 报错,因为unknown类型的变量不能赋值给其他类型
// void代表没有返回类型的函数
function fc(): void {
}
// never类型的函数代表永远不会有返回结果,例如报错了就抛异常了。
function fn2(): never {
throw new Error('报错')
}
// object代表一个JS对象
let a: object
a = {
}
a = function () {
}
// {}用来指定对象中可以包含哪些属性,
let b: {
name: string, age: number }
// 语法:{属性名:属性值}
b = {
name: 'hello', age: 18 }
注意: 如果说按照上面的写法,我定义了b对象,包含3个属性,但是在赋值的时候,缺只操作了2个属性,这样写是报错的:
因此,只要在对应的属性名后加上一个”?“,就能表示该属性是可选的,就不会报错了,如下:
若对某个对象进行赋值的时候,可以自定义任意个数的属性,该怎么办?
// [proName: string]: any 表示任意类型的属性
let b: {
name: string, [proName: string]: any }
// 但是还是要求,进行赋值的时候,必须对name进行赋值
b = {
name: 'hello', age: 18, a: 1, b: 2, c: false }
/**
* 定义数组的两种方式:
* 1.let a: xxx[]
2.let b: Array
*/
let a: string[]
let b: Array<string>
a = ['a', 'b', 'c']
// 定义元组,此时的数组长度是固定的
let c: [string, number]
c = ['hello', 123]
// c = ['hello', 123, 444] 报错,因为超过了定义的数组长度
enum Gender {
Male, // 值为0
Female // 值为1,并且接下来的值都是单调递增
}
enum Gender2 {
Male = 3, // 值为3
Female // 值为4,并且接下来的值都是单调递增
}
enum Gender3 {
Male = '男', // 值为男
Female = '女' // 值不会单调递增,因为是字符串,并且必须赋值
}
// 访问
let i: {
name: string, gender: number }
i = {
name: 'Hello',
gender: Gender.Male
}
// & 的意思是,aa必须同时满足下面两个对象
let aa: {
name: string } & {
age: number }
// 报错 a={name:'张三'}
aa = {
name: '张三', age: 1 }
// 写法1
// 意思是,变量b的值可以是1,2,3,4,5的任意一个
let b: 1 | 2 | 3 | 4 | 5
let d: 1 | 2 | 3 | 4 | 5
// 写法2,更加简洁
type myType = 1 | 2 | 3 | 4 | 5
let bb: myType
let dd: myType
编译文件的时候,我们使用 -w
指令后,那么TS编译器就会自动监视文件的变化,并在文件发生变化的同时对文件进行重新编译。
tsc xxx.ts -w
相关文件随意进行改动,如添加一个变量:
此时控制台会输出:
那么对应的js文件就会多出这么一行代码:
但是这种方式会有一个很明显的问题:
解决方案:
项目中添加一个文件即可:tsconfig.json
简写命令:tsc -w
tsconfig.json
是ts编译器的配置文件,ts编译器可以根据他的信息来对代码进行编译。
一部分配置如下:
{
// include用来指定哪些ts文件需要被编译
"include": [
// **代表任意目录,*表示任意文件
"./src/**/*"
],
// exclude代表不需要被编译的文件目录
"exclude": [
"./src/hello"
],
/*
* compilerOptions表示编译器的选项,其中包含很多个子选项
*/
"compilerOptions": {
// target:指定ts被编译后,为ES6版本
"target": "ES6",
// module:指定要使用的模块化的规范
"module": "system",
// lib:指定项目中要使用的库
"lib": [
"es6",
"dom"
],
// outDir:用来指定文件编译后的所在目录
"outDir": "./dist",
// outFile:用来将所有的代码合并为一个文件
"outFile": "./dist/app.js",
// allowJs:是否编译Js,默认是false
"allowJs": false,
// 是否检查js代码是否符合语法规范
"checkJs": false,
// 是否移除注释,默认false,true则编译出的文件不包含注释
"removeComments": true,
// 当有错误的时候不生成编译后的文件
"noEmitOnError": false,
// 用来设置编译后的文件是否使用严格模式,默认是false
"alwaysStrict": true,
// 不允许隐式的any类型
"noImplicitAny": true,
// 不允许不明确类型的this
"noImplicitThis": true,
// 严格的检查空值
"strictNullChecks": true
}
}