《深入理解 TypeScript》笔记之 Typescript 类型系统(一)

274 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

1. 概览

1.1 原始类型

Javascript 的原始类型适用于 Typescript 的类型系统,因此 number,string,boolean 也可以作为类型注解

let num: number;
num = 34;
num = "34"; // Error

let str: string;
str = "34";
str = 34; // Error

let bool: boolean;
bool = true;
bool = 0; // Error

1.2 数组

Typescript 的数组注解需要使用后缀[],然后再根据数组元素的类型添加具体的类型注解。

let boolArray: boolean[];
boolArray = [false, true];
boolArray[1] = "true"; // Error

1.3 接口

接口可以将多个类型注解合并成一个类型注解。

interface FullName {
  first: string;
  second: string;
}
let fullName: FullName;
fullName = {
  first: "Li",
  second: "Ming",
};
fullName = {  // error TS2741: Property 'second' is missing in type
  first: "Hi",
};

1.4 内联类型注解

可以快速提供一个类型注解,相比通过接口的方式创建注解,该方法更加便捷。不过,当该注解需要多次使用的时候,重构为一个接口会更加友好。

let fullName: {
  first: string;
  second: string;
};
fullName = { // error TS2741: Property 'second' is missing in type
  first: "Hi",
};

1.5 特殊类型

  1. any 类型。使用 any 类型后 Typescript 将会关闭类型检查,也就是说它可以兼容所有的类型,任何类型都可以赋值给它,它也可以赋值给任何类型。在 Javascript 转 Typescript 的时候会经常使用它,但是为了类型安全,应该尽量少使用它。
let power: any;
power = "hello";
power = true;

let num: number = 34;
num = power;
  1. null 和 undefined。Javascript 中的 null 和 undefined 字面量可以赋值给任意类型的变量。
let str: string;
str = null;
str = undefined;
  1. void。使用 :void 表示一个函数没有返回值
function log(message: string): void {
  console.log(message);
}

1.6 泛型

泛型是表示任意类型注解的模版。当函数在传入参数和返回参数使用泛型的时候,传入参数和返回参数的数据类型需要保持一致。

function reverse<T>(items: T[]): T[] {
  let res = [];
  for (let i = items.length - 1; i >= 0; i--) {
    res.push(items[i]);
  }
  return res;
}
let test = [3, 5];
let reversed = reverse(test);
reversed = [4, 5];
reversed[0] = "4"; // error TS2322: Type 'string' is not assignable to type 'number'.

1.7 联合类型

通过标记“|”使用该类型,可以同时支持多个类型注解

function fn(items: string | number) {
  return items;
}
fn(34);
fn("34");

1.8 交叉类型

通过交叉类型可以使用 extend 模式,该模式可以将接收的两个对象合并成一个对象并返回。

function extend<T extends Object, U extends Object>(num1: T, num2: U): T & U {
  let result = <T & U>{};
  for (let key in num1) {
    (<T>result)[key] = num1[key];
  }
  for (let key in num2) {
    (<U>result)[key] = num2[key];
  }
  return result;
}
let res = extend({ name: "leon" }, { age: 23 }); // 现在 res 拥有了 name 和 age 属性
const a = res.name;
const b = res.age;

1.9 元组类型

Typescript 支持元组类型,相比于数组类型注解,元组类型注解规定了元素的个数及其对应的类型

let nameNumber: [string, number];
nameNumber = ["leon", 24];

1.10 类型别名

Typescript 提供了给类型注解提供别名的快捷语法

type strOrNum = string | number;
let sample: strOrNum;
sample = 34;
sample = "34";

1.11 小结

Typescript 为了支持原始类型,提供了 number,string,boolean 类型注解;为了支持数组,提供了数组类型注解;为了支持对象,提供了快捷的内联类型注解以及更加通用的接口;针对特殊类型,提供了支持所有类型的 any 类型,可以赋值给任意类型的 null 和 undefined,以及提供函数返回空值的 void 类型。

另外,为了增加灵活性和复用,使用了泛型来实现支持不同类型注解的模版,使用了联合类型来同时支持多个类型注解,使用了交叉类型来实现多种类型注解的合并判断。

最后,提供了固定元素长度及其类型的元组,还有给类型注解提供别名的快捷语法。

本篇用时4个小时