优势

  1. ts的静态类型使得我们在开发过程中,发现潜在问题;
  2. 编辑器可以给出更好的代码提示;
  3. 代码语义更加清晰易懂,类型声明可以直观的看到代码中潜在语义,这样写出的代码可读性会更高一些;
  1. // type Point = {x: number, y: number} // 这是一种类型别名的语法
  2. interface Point {x: number, y:number}
  3. function tsDemo(data: Point) {
  4. return Math.sqrt(data.x ** 2 + data.y ** 2)
  5. }
  6. tsDemo({x: 1, y: 2});

编辑器配置

vscode 设置,

  • tab size 设置为 2
  • Quote Style 设置为 single
  • 为了格式化文档,我们安装插件: Prettier - Code formatter
  • 勾选 Editor: Format On Save
  1. npm install -g typescript

此时运行 node demo.ts 是不行的,浏览器或者node环境中是不能运行ts的。
我们需要先 tsc demo.ts 把代码编译成 demo.js
然后执行 node demo.js

为了解决这个问题,我们安装 ts-node , 然后执行 ts-node demo.ts

  1. npm install -g ts-node
  2. // 如果执行 ts-node demo.ts 报错 console.log(...) 可以安装下面的依赖:
  3. npm install -D tslib @types/node

静态类型深度理解

  1. const count: number = 2021;

count 为number类型后,count 这个变量会具备 number 类型所有的属性和方法

  1. // 自定义变量
  2. interface Point {
  3. x: number,
  4. y: number
  5. }
  6. const point: Point = {} // 这样定义一个Point类型是会报错的,我们可以写成后面的形式:
  7. const point: Point = { // 这样写就不会报错了
  8. x: 3,
  9. y: 4
  10. }

理解

  • Point 类型是一个自定义的静态类型
  • point 变量上具备Point静态类型上的属性和方法

定义静态类型后不仅意味着数据类型不能修改,而且对应变量上的方法和属性基本也就确定了,正是因为这样,编辑器在使用静态类型的时候,才能给我们很好的提示。 这就是我们所说的 type 的深度理解。

基础类型和对象类型

静态类型可以帮助我们更直观的判断变量的内容是什么,比如 let count: number 我们就可以知道 count 的内容一定是数字,否则就不对了。

  1. // 基础类型 null, undefined, symbol, boolean, void...
  2. const count: number = 123;
  3. const job: string = 'web开发';
  4. //对象类型: 对象、数组、类、函数类型等
  5. const person: {
  6. name: string,
  7. age: number
  8. } = {
  9. name: 'cos',
  10. age: 18
  11. }
  12. const arr: number[] = [1, 2, 3];
  13. class Phone {}
  14. const iphone: Phone = new Phone();
  15. // getTotal 是一个函数类型,函数执行的返回值是一个数字类型
  16. const getTotal: () => number = () => {
  17. return 123;
  18. }

类型注解和类型推断

type annotation 类型注解,我们来告诉TS变量是什么类型

type inference 类型推断,TS会自动的尝试分析变量的类型

如果ts能够自动分析变量类型,我们就什么也不需要做了
如果ts无法分析变量类型的话,我们就需要使用类型注解

  1. // 这些ts是可以推断类型的,我们就不用使用类型注解了
  2. const num1 = 1;
  3. const num2 = 2;
  4. const total = num1 + num2;
  5. const obj = {
  6. name: 'cos',
  7. age: 28
  8. }
  9. // 这里的x,y 是无法推断类型的,所以就要使用类型注解
  10. function getTotal(x: number, y: number) {
  11. return x + y;
  12. }
  13. getTotal(1, 2);

函数相关类型

ts中定义函数的方式和JS中定义函数的方式是一致的

  1. function func() {}
  2. const func = function() {}
  3. const func = () => {}
  1. // 一般来说类型推断可以帮我们确定数据类型,但是像这种函数返回值的类型一般我们是需要写类型注解的,
  2. // 因为有时候可能会在函数内部错误书写导致数据类型发生变化,所以我们一般是要声明函数返回值数据类型的
  3. function add(first: number, second: number): number {
  4. return first + second;
  5. }
  6. const total = add(1, 2);
  1. // void 表示函数不应该有返回值
  2. function func(): void {
  3. console.log('func'); // 这样写时不会报错的
  4. return 'func'; // 如果这样写就会报错
  5. }
  1. // never 表示函数永远不可能执行到最后
  2. function errorEmitter(): never {
  3. throw new Error();
  4. console.log('never');
  5. }
  6. // 还有哪些函数式永远知行不到最后的呢:
  7. while(true) {}
  8. // ... 这里的函数是执行不完的
  1. // 函数解构
  2. function add({first, second}: {first: number, second: number}): number {
  3. return first + second;
  4. }
  5. const total = add({first: 1, second: 2});
  6. // 注意:只要是解构都必须 按照上述的语法写,即便是只有一个参数
  7. function add({first}: {first: number}): number {
  8. return first;
  9. }

复习

  1. // 基础类型 boolean number string void undefined symbol null
  2. let count: number;
  3. count = 123;
  4. //注:如果分成两行来写,则需要类型注解
  1. // 对象类型: {} , class, function, []
  2. // 如果我们希望函数的参数和返回值都有固定的数据类型,有2种方式可以约束参数和返回值
  3. // 例:字符串 转 数字
  4. const func = (str: string): number => { // 这里其实不写number 类型推断也能推断出返回值为number
  5. return parseInt(str, 10);
  6. }
  7. // 所以我们可以写成这样:
  8. const func = (str: string) => {
  9. return parseInt(str, 10);
  10. }
  11. // 但是这种写法是不能省略 number 的,否则语法就不正确了
  12. const func1: (str: string) => number = (str) => {
  13. return parseInt(str, 10);
  14. }
  15. /*
  16. : 后面跟的一般是类型
  17. = 后面跟的是具体实现
  18. 函数的入参一般是需要类型注解的
  19. 但是返回往往可以通过类型推断推断出结果
  20. */
  21. const date:Date = new Date();// 这里其实不需要写Date类型,因为ts可以推断出类型为Date
  22. const date = new Date();
  23. // 其他的case
  24. interface Person {
  25. name: string
  26. }
  27. const rawData = '{"name": "cos"}';
  28. const newData: Person = JSON.parse(rawData); // 这种JSON方法处理的数据是无法通过类型推断得出结论的,所以我们需要类型注解
  29. // 如果 一个变量可能是数字类型 也可能是 字符串类型
  30. let temp: number | string = 123; // 这里不能用 const? 为什么?
  31. temp = '456'

数组

  1. const numberArr: number[] = [1, 2, 3]; // 是一个数组,并且每一项都是数字
  2. // 如果数组中既有number 又有 string, 应该如何写类型注解:
  3. const arr: (number | string)[] = [1, '2', 3]; // 这就表示这个数组既有数字又有字符串
  4. const stringArr: string[] = ['a', 'b', 'c'];
  5. const undefinedArr: undefined[] = [undefined]; // 这个数组就只能有undefined,否则就回报错

// 数组中也可以存储复杂的数据类型

  1. const objArr: {name: string, age: number}[] = [{name: 'cos', age: 18}]
  2. // 这种写法读起来比较复杂,不容易理解

我们可以使用类型别名:
type alias:类型别名。

  1. type User = {name: string, age: number }
  2. const objectArr: User[] = [{
  3. name: 'cos',
  4. age: 18
  5. }]

注意:

  1. class Teacher {
  2. name: string,
  3. age: nuber
  4. }
  5. const objectArr: Teacher[] = [
  6. new Teacher(),
  7. {
  8. name: 'cos',
  9. age: 28
  10. }
  11. ]
  12. // 这里虽然我们写了类型危 Teacher ,
  13. // 但是 不通过 new Teacher() 这种形式也是可以的,只要是传递一个对象,里面结构和Teacher保持一致即可

元组 tuple

当一个数组长度固定,且没个元素的类型固定的时候,就可以把该数组称为一个元组了。

比如,有一个数组,第一项为字符串,第二项为字符串,第三项为数字,

  1. const info = ['cos', 'male', 18];
  2. // 这种我们写成数组的话:
  3. const info: (string | number)[] = ['cos', 'male', 18];
  4. // 这种写法中,我数组中的3个值只要是string或者number类型就可以,就约束不住了,
  5. // 这个时候我们可以考虑使用元组:
  6. const info: [string, string, number] = ['cos', 'male', 18];
  7. // 这个时候我们就可以把这3个元素唯一约束了。

比如 excel中导出的 .csv所产生的数据结构,在转化成js的时候,用元组去管理是一个比较好的方式。

  1. const arr: [string, string, number][] = [
  2. ['cos', 'meal', 18],
  3. ['rose', 'meal', 28],
  4. ['jack', 'femeal', 8],
  5. ];