目录
一、ts与es、js之间的关系
二、TypeScript与JavaScript之间的区别
三、安装TypeScript编译器
四、执行typescript的步骤
五、ts的数据类型
1、类型别名
2、接口
接口 与 类型别名 的区别
3、类型断言
4、文字类型
不常用枚举、bigint、symbol
六、类型缩小
1、typeof 类型守卫
2、真值缩小
3、等值缩小
4、操作符缩小
never类型
一、ts与es、js之间的关系
二、TypeScript与JavaScript之间的区别
TypeScript | JavaScript |
ts是js的超集,用于解决大型项目的代码复杂性 | js一种脚本语言,主要用于创建动态网页 |
ts可以在编译期间发现并纠正错误 | js作为解释型语言,只能在运行时发现错误 |
ts是强类型的,支持静态和动态类型 | 是弱类型的,无静态类型选项 |
ts最终被编译成js代码,便于浏览器理解 | 可直接在浏览器中运行 |
支持模块、泛型和接口 | 不支持模块、泛型和接口 |
支持es3、es4、es5以及es6+的功能 | 不支持编译其他es3、es4、es5以及es6+的功能 |
三、安装TypeScript编译器
npm install typescript -g
//或
npm i typescript -g
四、执行typescript的步骤
1、进入要编译的ts文件目录下,在终端中输入:
tsc filename.ts
2、执行上述命令后会在该目录下生成一个对应的js文件,运行该文件:
node filename.js
3、ts中的优化编译
3.1、解决ts与js中冲突问题:
tsc --init #生成配置文件
3.2、自动编译
tsc --watch
3.3、发生错误的处理
tsc –noEmitOnError filename.ts
3.4、降级编译
在tsconfig.json配置文件里,将编译的es6编程es5
/* Language and Environment */
"target": "es5",
3.5、严格模式的设置(根据需求将对应的模式注解或该位false)
/* Type Checking */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
五、ts的数据类型
// 一、基元类型 Number String Boolean
let num: Number = 1;
let str: String = "hello";
let bool: Boolean = true;
// 二、数组
let arr:Number[] = [1,2,3,4] //只用整数组成的数组
let arrTy: Array<基元类型> = [];
// 三、不希望在某些时候导致类型检查错误 => any
let data: any; // data 可以是任何类型,这与原生的js变量一样
// 四、函数 函数的参数在大多数时候还是建议带上类型注释的,这样可以防止函数的参数变为隐式的 any 类型
function fn(num: Number){
console.log(num)
}
// 五、对象类型 其中在obj中的属性 b 后面加一个 ? 表示该值可穿可不穿;其类型为 Number | undefined
function obgFun(obj:{a:Number,b?:Number}){
console.log("obj.a的值为",obj.a);
console.log("obj.b的值为",obj.b);
}
obgFun({a:1})
obgFun({a:1,b:2})
// 六、联合类型(union) :有两个或多个其他类型组成的类型
let data: Number|String; //表示变量 data 可以是一个Number 也可以是 String。后面可以继续接其他数据类型
1、类型别名
通过了解ts的数据类型之后,发现有时候在多次使用某种数据类型的时候(尤其是 联合类型和对象类型)就会很麻烦,这个时候可以通过关键字type将某种数据类型赋值给一个变量,这个过程就是定义类型别名。
// 定义类型 别名
type spot = {x: Number,y: Number}
type ID= Number | String
// 使用类型别名
function printSpot(op: spot){
console.log(op)
}
printSpot({
x: 1,
y: 6
}) // 打印结果 {x: 1, y: 6}
2、接口
接口的作用其实跟类型别名是一样的,都是重新定义类型。
// 接口的定义和使用与 类型别名 几乎差不多
interface spot {
x: Number,
y: Number
}
// 使用接口
function printSpot(op: spot){
console.log(op)
}
printSpot({
x: 1,
y: 6
}) // 打印结果 {x: 1, y: 6}
接口 与 类型别名 的区别
相同点:
两者都是用来定义数据类型的
不同点:
在扩展数据类型的方式上不同<接口通过关键字 extends 去扩展数据类型,类型别名则是通过 & 去实现扩展的;接口可通过重复定义实现添加,但类型别名不可以,类型别名只能通过 & 去添加>
Tip: 所有可以使用接口定义的类型,都可以使用类型别名去定义。
// 接口定义数据类型
interface Person {
name: String
}
// 接口扩展数据类型
interface man extends Person{
name: String,
sex: String
}
// 接口的另一种扩展方式 => 重复定义(类型别名不可以使用这种方式)
interface man {
name: String
}
interface man {
sex: String
}
// =======================================================
// 类型别名 定义数据类型
type Person = {
name: String
}
// 类型别名 扩展数据类型
interface man = Person & {
name: String,
sex: String
}
3、类型断言
类型断言是指在不确定某个变量的类型时,给其指定一个确切的类型。
// 使用 as 语法 或是 在变量前面添加 <具体数据类型> 来完成数据断言
let canvasData = document.getElementById("canvased") as HTMLCanvasElement;
// 或
let canvas = <HTMLCanvasElement>document.getElementById("canvased");
4、文字类型
文字类型 跟JS中的 常量 很像。就是定义完变量就不再允许变量的值被修改。
// 字符串文字类型
let a: "hello" = "hello" // 变量a 只能是 hello,不允许被修改,如果重新赋值会报错
// 数值文字类型 这里函数的返回值只能是0 1 -1,如果返回其他值就会报错
function returnNum(Numa:Number,Numb:Number): 0|1|-1{
return Numa > Numb ? 1 : Numa === Numb ? 0 : -1
}
// 布尔文字类型
let BoolA: true = true // 变量BoolA的值只能是true
let BoolB: false= false // 变量BoolB的值只能是false
// 文字类型的联合使用 (比较重要,文字类型使用的注意场景)
function request(url: String,method: 'GET'|'POST'|'PUT'){
console.log("请求的url为:",url)
}
let req = {
url: "http://127.0.0.1:8080",
method: "GET" // as 'GET'
} // as const
request(req.url,req.method) // 这样直接使用会报错,因为在定义req 的时候req.method被推断为字符串,与方法中的method的文字类型不一致
request(req.url,req.method as "GET") //使用的时候加上类型断言
不常用枚举、bigint、symbol
// 定义枚举
enum position = {
top:1,
bottom,
left,
right
}
console.log(position.top) // 打印 1
console.log(position.bottom) // 打印 2 自动累加赋值
// bigint 表示一个非常大的数值
let Num: bigint = BigInt(100)
// symbol 唯一的值
let Fname = symbol("name");
六、类型缩小
类型缩小主要是将宽类型范围转换为窄类型范围,主要是应在 联合类型 的使用上面。
1、typeof 类型守卫
使用typeof去做数据类型的判断,从而达到类型缩小的目的(注意类型object与null的关系有时候类型为object的变量可能会隐式转换为null)。
2、真值缩小
function returnData(data: String | String[] | null){
// 这里如果 typeof data === 'object'判断的话,就会报错,因为 data 也可以推断为 null,但是如果使用 data && typeof data === 'object'进行判断就排除了 data 为null的情况(真值缩小)
if(data && typeof data === 'object'){
for(const i of data){
console.log(i);
}
}else if(typeof data === 'string'){
console.log(data);
}else{
// ....
}
}
3、等值缩小
利用等于 或 不等于(===、==、!==、!=)的运算符去判断数值之间的关系,从而达到类型缩小(尤其是==与!=,在某些特定的场景下,可以过滤出undefined与null)
4、操作符缩小
使用操作符 in 或 instanceof去判断数据是否被包含在某个范围内 或 是否为某一个对象的实例从而达到类型缩小的目的。
never类型
never类型可以分配给每个类型;但是,没有任何类型可以分配给never(除了never本身)。这意味 着你可以使用缩小并依靠 never 的出现在 switch 语句中做详尽的检查(可在判断中进行穷尽性检查)。