# TypeScript

TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程

# 如何编译 ts 文件

我们可以直接使用 ts-node 来执行 ts 文件,或者使用 tsc 来将 ts 文件编译成 js 文件后在执行

# ts-node

$ npm i -g ts-node
$ npm install -g typescript
$ ts-node foo.ts

# tsc

$ npm i --save-dev typescript
$ npx tsc -p ./tsconfig.json

# 如何调试 ts 文件

本章介绍使用如何 vscode 来调试 ts 文件

// launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Current TS File",
      "type": "node",
      "request": "launch",
      "program": "${workspaceRoot}/node_modules/ts-node/dist/bin.js",
      "args": ["${relativeFile}"],
      "cwd": "${workspaceRoot}",
      "protocol": "inspector",
      "env": { "TS_NODE_PROJECT": "tsconfig.base.json" } // 使用该环境变量指定具体的tsconfig文件,默认为tsconfig.json
    }
  ]
}

# TypeScript 知识点收集

本章介绍一些编写 TS 代码中比较重要的知识点

# 泛型

个人简单理解泛型就是让我们可以像函数一样接收一个参数来动态的设置类型,本节收集整理在泛型的使用过程中的一些高级用法

# 泛型约束

使得 Foo 类型传入的对象必须包含在接口 Initial 的属性之中

interface Initial {
  foo: string;
}

type Foo<T extends Initial> = {
  [key in keyof T]: T[key];
};

type Bar = Foo<{ foo: string }>;

# 参数扩展

通过此方式,我们可以设置一些默认的接口参数,然后通过泛型的方式,来让调用者可以扩展默认的接口

interface Initial {
  foo: string;
}

type Foo<T = {}> = T & {
  [key in keyof Initial]: Initial[key];
};

type Bar = Foo<{ bar: string }>;

# 复合类型转 Map

type Union = "a" | "b" | "c";

type UnionToMap = {
  [key in Union]: string;
};

# Map 转复合类型

type MyMap = {
  foo: string;
  bar: number;
};

type MapToUnion = MyMap[keyof MyMap]; // string|number

# 类型转换为 Optional

interface Foo {
  foo: string;
  bar: string;
}

type Optional<T> = { [key in keyof T]?: T[key] };

type OptionalFoo = Optional<Foo>;

# 类型转换为 readonly

interface Foo {
  foo: string;
  bar: string;
}

type Optional<T> = { readonly [key in keyof T]: T[key] };

type OptionalFoo = Optional<Foo>;

# 接收多个参数,Union 转 Map

type Foo<T extends keyof any, O> = { [key in T]: O };

type Size = "small" | "default" | "big";

type SizeMap = Foo<Size, number>;

# 递归添加 readonly

type DeepReadony<T> = {
  readonly [P in keyof T]: DeepReadony<T[P]>;
};

interface SomeObject {
  a: {
    b: {
      c: number;
    };
  };
}

const obj: DeepReadony<SomeObject> = { a: { b: { c: 2 } } };