TypeScript

2022-07-09· 20min

TypeScript,一种基于 JavaScript 的强类型编程语言

#开发优势

  • 类型安全,在编码阶段避免潜在的编码错误
  • 更好的 IDE 支持,如代码跳转定义、补全提示等
  • 强大的类型系统,对于大型项目、多人协同编码时,使代码更具可读性、可维护性

#语法小结

#数据类型

  • 支持 JavaScript 数据类型:基础数据类型、引用数据类型
  • Enum 枚举
    enum Color {
      Red = 1,
      Green,
      Blue,
    }
    let cName1: string = Color[2];
    let cName2: number = Color.Green;
    console.log(cName1, cName2); // Green, 2
    
  • Tuple 元组
    let arrT: [string, number] = ["hello", 10];
    
  • Any
    • 用于描述任意类型的变量,不作任何约束,跳过编译阶段的检查
    let v: any = "string";
    v = false;
    
  • Void
    • 表示无任何类型
    // 如:没有返回值的函数的返回值类型
    function fn(): void {
      console.log("No return");
    }
    
  • Never
    • 表示的是那些永不存在的值的类型
    • 是任何类型的子类型,也可以赋值给任何类型
    // 抛出异常
    function error(message: string): never {
      throw new Error(message); // 抛出异常会直接中断程序运行,即永不存在返回(具有不可达的终点)
    }
    
    // 死循环
    function loopForever(): never {
      while (true) {} // 程序无法运行到函数返回值那一步,即永不存在返回
    }
    
  • Unknown
    • 表示未知类型
    let v: unknown = "string";
    v = false;
    

#类型限定

  1. 类型推断
// TS 可以自动推断出变量的类型
let str = "ssss";
str = 10; // Type 'number' is not assignable to type 'string'.
  1. 类型注解
let str: string = "ssss";
  1. 类型断言
let str: any = "ssss";
// as关键字
let strLen: number = (str as string).length;
// 尖括号语法
let strLen: number = (<string>str).length;

#关键字

#keyof

  • 用于获取某个类型的所有键,并将其作为联合类型返回
interface Person {
  name: string;
  slogan: number;
}

type PersonKeys = keyof Person; // "name" | "slogan"

#in

  • 用于创建映射类型时,遍历联合类型中的每个成员
// 例子一:
type PersonKeys = "name" | "slogan";
type Person1 = {
  [K in PersonKeys]: string | number;
};
// 同下:
type Person1 = {
  name: string | number;
  age: string | number;
};

// 例子二:
type Person2 = {
  name: number;
  age: number;
};
type Person3 = {
  [K in keyof Person2]: string;
};
// 同下:
type Person3 = {
  name: string;
  age: string;
};

#keyof

  • 用于获取变量或表达式的类型
// 例子一:
let personName = "Alice";
type NameType = typeof personName; // string

// 例子二:
const person3 = {
  name: "str",
};
type PersonType = typeof person3;
// 等同于:
type PersonType = {
  name: string;
};

#infer

  • 用于在条件类型中进行类型推断。在条件类型中提取并命名一个类型,然后在该条件类型的返回部分中使用。
type ParamType<T> = T extends (arg: infer P) => any ? P : T;
interface Person {
  name: string;
}

type MyFn = (person: Person) => void;
type ParamPenson = ParamType<MyFn>; // Person
type ParamStr = ParamType<string>; // string

#extends

  • 类型组合
interface N1 {
  name: string;
}
type S1 = {
  slogan: string;
};
interface NS extends N1, S1 {}

let ns1: NS = {
  name: "p1",
  slogan: "s1",
};
  • 类型约束
type IsStr<T> = T extends string ? true : false;
type Box<T> = {
  val: T;
  isString: IsStr<T>;
};
const stringBox: Box<string> = {
  val: "str",
  isString: true,
};
  • 继承
class Person1 {
  public name: string = "str";
}
class Person2 extends Person1 {
  public slogan: string = "sl1";
}

const pp = new Person2();
console.log(pp.slogan); // sl1

#工具类型

#Partial<T>

// 定义:将 T 中所有的属性都变成可选类型
type Partial<T> = {
  [P in keyof T]?: T[P];
};

// 示例
type Person = {
  name: string;
  slogan: string;
};
const Person2: Partial<Person> = {
  name: "p2",
};

#Pick<T, K>

// 定义:从 T 中摘取部分属性
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

// 示例
type Person = {
  name: string;
  slogan: string;
  sex: string;
};
const Person3: Pick<Person, "name" | "sex"> = {
  name: "p3",
  sex: "male",
};

#Exclude<T, U>

// 定义:从 T 中剔除可以赋值给 U 的类型
// 条件类型,如果 T 可以分配给 U,则是 never,否则是 T
type Exclude<T, U> = T extends U ? never : T;

// 示例
type Ta = string | number;
type Tb = number;
type Tc = Exclude<Ta, Tb>;

const tc1: Tc = "str";

#Extract<T, U>

// 定义:提取 T 中可以赋值给 U 的类型
type Extract<T, U> = T extends U ? T : never;

// 示例
type Ta = string | number;
type Tb = number;
type Tc = Extract<Ta, Tb>;

const tc1: Tc = 1;

#Omit<T, K>

// 定义:从 T 中排除部分属性
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

// 示例
type Person = {
  name: string;
  slogan: string;
};
const Person4: Omit<Person, "slogan"> = {
  name: "p4",
};

#Readonly<T>

// 定义:将 T 的所有属性变为只读属性
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

// 示例
type Person = {
  name: string;
};
type PersonReadonly = Readonly<Person>;
const person: PersonReadonly = {
  name: "p6",
};

person.name = "p8"; // Cannot assign to 'name' because it is a read-only property.

#Required<T>

// 定义:将 T 中所有的属性都变成必选类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

// 示例
type Person = {
  name: string;
};
type PersonReadonly = Readonly<Person>;
const person: PersonReadonly = {
  name: "p5",
};

person.name = "p6"; // Cannot assign to 'name' because it is a read-only property.

#Record<K, T>

// 定义:返回属性名为 K,属性值为 T 的类型
type Record<K extends keyof any, T> = {
  [P in K]: T;
};

// 示例
type Str2Num = Record<string, number>;
const str2num: Str2Num = {
  a: 1,
  b: 2,
  c: 3,
};

#Parameters<T>

// 定义:获取函数参数类型组成的元组
type Parameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never;

// 示例
type MyFn = (a: number, b: string) => void;
type MyFnParameters = Parameters<MyFn>; // [number, string]

#参考文献