ts的学习

82 阅读4分钟

TS给js添加一种类型约束,使得代码更加严谨规范。

更加严谨。编写代码的时候静态类型的校验。

npm i -g typescript@4.5.2

安装成功后执行tsc -v就可以查看到版本了。

在项目文件夹中执行tsc -init表示ts初始化项目

tsc -init

编译当前项目文件夹的ts文件到指定的目录下:

tsc -p tsconfig.json

开启服务,监听编译当前项目文件夹的ts文件到指定的目录下:

tsc -p tsconfig.json --watch 或者
tsc -p tsconfig.json -w

二、原始类型

string,number,boolean,symbol,null,undefined

export {}; // 第一行增加这个是为了使文件里的变量不污染全局
let num: number = 1; // number
let str: string = "2"; // string
let bool: boolean = true; // boolean
let sy: symbol = Symbol(); // symbol
let undef: undefined = undefined; // undefined
let nul:null = null; // null
let vd: void = undefined; // 可以把undefined类型赋值给void类型,但是反过来不行
// 函数没有返回值,那么函数的返回值类型就是void
function fn(): void {
  return undefined;
}

注意:

  1. void只用在函数没有返回值的情形下。
  2. undefined和null最大的价值主要体现在接口类型上,表示可缺省、未定义的属性;null表示对象或者属性是空值。 这个可以先有个印象,后面说到接口会讲
  3. 如果不写类型,typescript是可以推断类型的,但注意let、const的区别

三、非原始类型

1. 小object, 大Object, {}

小object:代表的是非原始类型的类型,也就是不能是string,number,boolean,symbol,严格模式:多包括null,undefined

let obj1: object = 3; // 报错
let obj2: object = "3"; // 报错
let obj3: object = true; // 报错
let obj4: object = null; // 报错
let obj5: object = undefined; // 报错
let obj6: object = Symbol(); // 报错
let obj7:object = {a: 1, b: '2'};
let obj8:object = [1, 2, 3];

大Object :代表所有拥有 toString、hasOwnProperty 方法的类型,所以所有原始类型、非原始类型都可以赋给 Object,严格模式下不包括null,undefined。{}空对象类型和大 Object 一样。

let obj1: Object = 3; 
let obj2: Object = "3"; 
let obj6: Object = Symbol(); 
let obj3: Object = true; 
let obj4: Object = null; // 报错
let obj5: Object = undefined; // 报错
let obj7: Object = { a: 1, b: "2" };
let obj8: Object = [1, 2, 3];

注意: 1. 官方文档说可以使用小 object 代替大 Object,但是我们仍要明白大 Object 并不完全等价于小 object。 2. 上面的例子看起来,大Object是小object的父类型,但并不是!!!真实的情况是大Object才是小object的子类型

2. 数组类型

数组类型的定义:

let arr1: Array<number> = [1, 2, 3];
arr1.push('3'); // 报错
arr1.push(5);
let arr2: string[] = ['4', '5', 'a'];
arr2[3] = '6';

3. 字面量类型

  • 字面量不仅可以表示值,还可以表示类型
let x3: 1 | 3 = 1;
x3 = 2; // 报错
x3 = 3;
​
let x4:'hello' = 'hello';
x4 = 'hi'; // 报错

注意:

  1. TypeScript 支持 3 种字面量类型:string字面量类型、number字面量类型、boolean字面量类型

4. 联合类型

可以把“|”类比为 JavaScript 中的逻辑或 “||”,只不过前者表示可能的类型。

let age: number | string = 20;

5. 交叉类型

在 TypeScript 中,还存在一种类似逻辑与行为的类型——交叉类型(Intersection Type),它可以把多个类型合并成一个类型,合并后的类型将拥有所有成员类型的特性。使用“&”操作符来声明交叉类型(并集)。

// 思考这里有一个值满足m的类型要求吗?
let m : string & number;
​
let zs: { name: string; age: number } & { height: number } = {
  name: "张三",
  age: 20,
  height: 180,
};

6. 联合、交叉组合

联合、交叉类型本身就可以直接组合使用,这就涉及 |、& 操作符的优先级问题。联合操作符 | 的优先级低于交叉操作符 &,同样,我们可以通过使用小括弧 () 来调整操作符的优先级,这个和js一样。

let m:{ id: number } & { name: string } | { id: string } & { name: number };
m = {
    id: 1,
    name: ''
}
​
m = {
    id: '',
    name: 1
}

四、any&&unknown

  • any 指的是一个任意类型,它是官方提供的一个选择性绕过静态类型检测的作弊方式。非常不建议使用;Any is Hell(Any 是地狱)
  • unknown 是 TypeScript 3.0 中添加的一个类型,它主要用来描述类型并不确定的变量。和any的区别就是会进行类型检测。
let unk: unknown;
let x = 1;
let y = "2";
if (x) {
    unk = x;
} else {
    unk = y;
}
​
// 使用unknown后,typescript会做类型检测
unk.toFixed(2); // 报错 
// any会绕过类型检测,所以下面不会有问题提示
let an1: any;
an1.toFixed(2);
​
// 通过缩小类型可以通过类型检测
if (typeof unk === 'number') {
    unk.toFixed(2);
}

注意: 1. 可以把任何类型的值赋值给unknown,但是unknown类型的值只能赋值给any或者unknown; 2. unknown比any好的地方,还有一个就是它可以通过缩小类型的手段类确定类型