TS | 青训营笔记

123 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天

为什么选择TS

  1. TS是静态类型语言,大部分错误可以在编译时检测出来。
  2. 拥有 IDE 的加强(类型提示等),会通过语法生成文档。
  3. 兼容 JS 的所有特性,可以与 JS 共存,并且最后编译出来也是 JS。

对于 Interface 与 Type 个人理解

类型使用 type

typeinterface 大部分功能相同,我认为在需要使用类型时(如声明参数、变量)应使用type,而不是使用interface,原因如下:

  1. interface会合并重复声明。
  2. type可以声明基本类型、联合类型、交叉类型、元组。
  3. 使用type时 IDE 可以查看具体的字段,interface则不行。

Interface 的样子:

interface

Type 的样子:

type

类使用 interface

在跟类相关时可以使用interfaceinterface与 C#、Java 基本作用一样。

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

Keyof

keyof 类型索引,可以通过它得到所有key组成的字符串字面量。

Infer

infer 可以推导泛型参数。


type ParamType<T> = T extends (arg: infer P) => any ? P : T;

interface User {
  name: string;
  age: number;
}

type Func = (user: User) => void;

type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string

infer P 表示待推断的函数参数,如果 T 能赋值给 (arg: infer P) => any,则结果是P,否则为 T

infer 只能在 extends 的右边使用,infer P 的 P 也只能在条件类型为 True 的一边使用。

协变与逆变

以下仅个人理解

协变:子类到父类上

逆变:父类到子类上

举个例子:

class Father {
  base = ''
}

class Children extends Father {
  type = 'children'
}

// 协变
const f: Father = new Children()

// 父
let funF = (f: Father) => {}
// 子
let funC = (c: Children) => {}

// 逆变
funC = funF

参数变量函数返回值中有不同的规则:

  1. 参数:只允许发生逆变,也就是子类到父类。
  2. 变量:只允许发生协变,也就是父类到子类。
  3. 函数返回值:与变量相同,只允许协变,父类到子类。

举个例子(开启严格函数类型检查):

class Father {
    base = ''
}

class Children extends Father {
    type = 'children'
}

// 变量协变
const f: Father = new Children()

// 变量逆变(不被允许)
const c: Children = new Father()  // Not Work.


// 参数逆变与协变
let funF = (f: Father) => {}
let funC = (c: Children) => {}

// 参数逆变
funC = funF

// 参数协变(不被允许)
funF = funC  // Not Work.


// 返回值协变与逆变
let funRF: ()=>Father = (f: Father) => new Father()
let funRC: ()=>Children = (c: Children) => new Children()

// 返回值协变
funRF = funRC

// 参数逆变(不被允许)
funRC = funRF  // Not Work.

TS在浏览器与Node环境中的使用

浏览器环境

Webpack/Vite

graph TD
配置Webpack --> 配置tsconfig --> 运行Webpack/Vite --> loader/esbuild处理ts文件并进行编译与检查

Node环境

graph TD
安装ts --> 配置tsconfig --> tsc编译 --> 运行编译的JS文件

可以配置package.json一键运行:

"scripts": {
  "run": "tsc <ts入口文件路径> && node <编译后的js入口文件路径>"
}

举个例子:

参考

TypeScript 协变和逆变

一文搞懂 infer

深入理解 TypeScript