# 第一章 入门配置
# 第二章 类型检测
# 第三章 函数类型
# 第四章 类和接口
# 第五章 枚举/promise
# 第六章 类型查找
# 第七章 特殊关键字
# const
- 将一个值的集合变成
readonly
const a = ["1", 2] as const;
a[1] = 3; // error
1
2
3
2
3
# Extract
- 从属性集里面摘出几个属性
type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// type T0 = "a"
1
2
3
2
3
function getAttr<T, K extends Extract<keyof T, string>>(o: T, p: K) {
// 对象属性键值原本是 symbol | string | number
const s: string = p;
return o[p];
}
getAttr({ name: "1" }, "name");
1
2
3
4
5
6
7
2
3
4
5
6
7
# ReturnType
- 函数的返回类型
const a = () => {
return "hello world!"
}
type b = ReturnType<typeof a>
// type b = string
1
2
3
4
5
6
2
3
4
5
6
# Enum
- 枚举类型
enum Res {
No,
Yes,
OR,
}
/* 同 */
// enum Res {
// No = 0,
// Yes = 1,
// OR = 2,
// }
// 直接获取
const no: Res = Res.No;
// 间接获取
const key = "Yes";
const yes = Res[key];
console.log(no);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# typeof
- 获取已知变量的对应的类型
enum UserResponse {
No,
Yes,
OR,
}
type all = keyof typeof UserResponse;
// type all = "No" | "Yes" | "OR"
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 索引访问类型
- 通过索引关系两个类型
type Person = {
name: string;
age: number;
friends: Person[];
}
type Name = Person["name"];
// type Name = "string"
type AgeName = Person["name" | "age"];
// type Name = string | number
type allPersonKeys = Person[keyof Person];
// type allPersonKeys = string | number | Person[]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 索引
number
访问所有类型生成新类型
const arr = [
{name: "黄", friends: ["a"]},
{name: "黄", age: 18},
];
type P = typeof arr[number]
/*
type P = {
name: string;
age?: undefined;
} | {
name: string;
age: number;
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 结合
const
固定类型,将数组类型
生成联合类型
const app = ["淘宝", "天猫", "支付宝"] as const;
type App = typeof app[number];
// type App = "淘宝" | "天猫" | "支付宝"
1
2
3
4
2
3
4
枚举索引
获取对象所有值类型
const person = {
name: "黄",
age: 18,
books: ["JS", "python"]
} as const;
type P = typeof person[keyof typeof person];
// type P = "黄" | 18 | readonly ["JS", "python"]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 三元表达式
type A = {
id: number;
}
type B = {
name: string;
}
// 三元表达式根据入参数判断返回值类型
function createLabel<T>(id: T): T extends number ? A : B;
function createLabel(id): A | B {
throw "unimplemented";
}
const a = createLabel(1);
// type a = A
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Exclude
interface Circle {
kind: "circle";
radius: number;
}
type KindlessCircle = {
[P in keyof Circle as Exclude<P, "kind">]: Circle[P];
}
// type KindlessCircle = {
// radius: number;
// }
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 配合泛型制造返回值
- 返回值比入参少属性
interface Circle {
kind: "circle";
radius: number;
}
function a<T, K extends keyof T>(
o: T,
p: K
): {
[P in keyof T as Exclude<P, K>]: T[P];
} {
delete o[p];
return o;
}
const c: Circle = {
kind: "circle",
radius: 10,
};
const x = a(c, "kind");
// const x: {
// radius: number;
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 映射类型
type isTypeHasFoot<T> = {
[P in keyof T]: T[P] extends number ? T[P] : never;
}
interface Animal {
foot: number;
hand: number;
head: string;
}
type B = isTypeHasFoot<Animal>;
// type B = {
// foot: number;
// hand: number;
// head: never;
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 模板字符串
enum Actions {
a = "click",
b = "touchstart",
c = "touchmove",
}
type enumIds = `on${Capitalize<Actions>}`;
// type enumIds = "onClick" | "onTouchstart" | "onTouchmove"
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 字符串内置操作符
enum Actions {
a = "click",
b = "touchstart",
c = "touchmove",
}
// 首字母大写
type A = `on${Capitalize<Actions>}`;
// type A = "onClick" | "onTouchstart" | "onTouchmove"
// 首字母小写
type D = `on${Uncapitalize<Actions>}`;
// type D = "onclick" | "ontouchstart" | "ontouchmove"
// 大写
type B = `on${Uppercase<Actions>}`;
// type B = "onCLICK" | "onTOUCHSTART" | "onTOUCHMOVE"
// 小写
type C = `on${Lowercase<Actions>}`;
// type C = "onclick" | "ontouchstart" | "ontouchmove"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# infer
- 类型推断,在表达式内推断出新类型
type InferTypes<Type> = Type extends () => infer Item ? Item : never;
type Fn = () => string;
type R = InferTypes<Fn>;
// type R = string
1
2
3
4
5
2
3
4
5
# 第八章 工具类型
key | 作用 |
---|---|
Partial | interface 属性全部变成可选类型 |
Required | interface 属性全部变成必填类型 |
Readonly | interface 属性全部变成只读类型 |
Record | 键的集合 和值生成新的类型 |
Pick | interface 内筛选出一部分属性作为新的类型 |
Omit | interface 内剔除掉一部分属性作为新的类型 |
Exclude | 联合类型 内剔除掉一部分属性作为新的类型 |
Extract | 联合类型 内提取出一部分类型作为新的类型 |
NunNullable | 联合类型 内剔除掉null /undefined 类型 |
Parameters | 函数类型 提取出参数类型 |
ConstructorParameters | 类 的构造函数的参数类型 |
ReturnType | 函数 的返回值类型 |
InstanceType | 类 的实例类型 |
PromiseLike | 符合Promise 的类型 |
# Partial
- 将一个属性集全部变成可选类型
interface People {
name: string;
age: number;
friends: People[];
}
type PeopleParams = Partial<People>
// type PeopleParams = {
// name?: string | undefined;
// age?: number | undefined;
// friends?: People[] | undefined;
// }
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Required
- 将一个属性集全部变成必填类型,与
Partial
相反
interface People {
name?: string;
age?: number;
friends?: People[];
}
type PeopleParams = Required<People>
// type PeopleParams = {
// name: string;
// age: number;
// friends: People[];
// }
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Readonly
- 将一个属性集全部变成只读
interface People {
name: string;
age: number;
friends?: People[];
}
type PeopleParams = Readonly<People>
// type PeopleParams = {
// readonly name: string;
// readonly age: number;
// readonly friends?: People[] | undefined;
// }
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Record
- 将一个键集合映射为一个值的集合,生成一个新类型
interface People {
name: string;
age: number;
friends?: People[];
}
interface Company {
boss: string;
marketing: string;
programer: string;
}
type CompanyPeoples = Record<keyof Company, People>
// type CompanyPeoples = {
// boss: People;
// marketing: People;
// programer: People;
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Pick
- 将一个类型筛选出一部分类型出来做成一个新类型
interface People {
name: string;
age: number;
friends?: People[];
}
type CompanyPeoples = Pick<People, "name" | "age">;
// type CompanyPeoples = {
// name: string;
// age: number;
// }
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Omit
- 将一个类型剔除掉一部分做出一个新的类型,和
Pick
相反
interface People {
name: string;
age: number;
friends?: People[];
}
type SchoolPeoples = Omit<People, "name" | "age">;
// type SchoolPeoples = {
// friends?: People[] | undefined;
// }
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Exclude
- 将一个
联合类型
剔除掉一部分做出一个新类型
type People = "boss" | "marketing" | "programer";
type SchoolPeoples = Exclude<People, "boss">;
// type SchoolPeoples = "marketing" | "programer"
1
2
3
4
2
3
4
# Extract
- 将一个
联合类型
提取出一部分做出一个新类型
type People = "boss" | "marketing" | "programer";
type SchoolPeoples = Extract<People, "boss">;
// type SchoolPeoples = "boss"
1
2
3
4
2
3
4
# NonNullable
- 把一个类型剔除掉
null
和undefined
type People = "boss" | null;
type SchoolPeoples = NonNullable<People>;
// type SchoolPeoples = "boss"
1
2
3
4
2
3
4
# Parameters
- 合并所有函数的参数类型
type Fn1 = (s: string) => string;
type Fn2 = (n: number) => void;
type SchoolPeoples = Parameters<Fn1 | Fn2>;
// type SchoolPeoples = [s: string] | [n: number]
1
2
3
4
5
2
3
4
5
# ConstructorParameters
- 一个
类
的构造函数的入参类型
type SchoolPeoples = ConstructorParameters<ErrorConstructor>;
// type SchoolPeoples = [message?: string | undefined, options?: ErrorOptions | undefined]
1
2
2
# ReturnType
- 一个函数的返回类型
type Fn1 = (s: string) => string;
type SchoolPeoples = ReturnType<Fn1>;
// type SchoolPeoples = string
1
2
3
4
2
3
4
# InstanceType
- 获取
class
的实例类型
直接拿
class
做类型是一样的,可能调用第三方库的时候有用
class A {
constructor() {}
}
type B = InstanceType<typeof A>;
const a: B = new A();
1
2
3
4
5
6
7
2
3
4
5
6
7
# PromiseLike
- 从
符合Promise规范
的表达式中拿到Promise返回值类型
type A<T> = T extends PromiseLike<infer U> ? U : never;
const a = Promise.resolve(10);
type B = A<typeof a>
// type B = number
1
2
3
4
5
6
2
3
4
5
6
# 装饰器
- 将多个
class
内共有的方法抽出来
@classDecorator
class Greeter {
property = "property";
hello: string;
constructor(m: string) {
this.hello = m;
}
}
console.log(new Greeter("world"));
function classDecorator(
constructor: typeof Greeter,
context: ClassDecoratorContext<typeof Greeter>
): void | typeof Greeter {
return class extends constructor {
newProperty = "new property";
hello = "override";
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 命名空间
# 追加声明
- 在一个已有的对象/类/模块内添加声明
function buildLabel(name: string): string {
return buildLabel.prefix + name + buildLabel.suffix;
}
namespace buildLabel {
export let suffix = "";
export let prefix = "Hello, ";
}
console.log(buildLabel("Sam Smith"));
console.dir(buildLabel);
// [Function: buildLabel] { suffix: '', prefix: 'Hello, ' }
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 做类型合并
- 给枚举添加函数类型
直接给枚举添加函数类型是不被通过的,可以通过命名空间追加导出的形式追加其他属性
enum Color {
red = 1,
green = 2,
blue = 4,
}
namespace Color {
export function mixColor(colorName: string) {
if (colorName == "yellow") {
return Color.red + Color.green;
} else if (colorName == "white") {
return Color.red + Color.green + Color.blue;
} else if (colorName == "magenta") {
return Color.red + Color.blue;
} else if (colorName == "cyan") {
return Color.green + Color.blue;
}
}
}
console.log(Color);
// {
// red: 1,
// green: 2,
// blue: 4,
// mixColor: [Function: mixColor]
// '1': 'red',
// '2': 'green',
// '4': 'blue',
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 模块声明文件
xxx.d.ts
文件追加已有的声明
- 只在本目录及子目录生效
# 声明扩展
- 扩展已有说明
declare module "react/jsx-runtime" {
declare global {
interface Window {
ActiveXObject: any;
isCloseHint: boolean;
}
namespace NodeJS {
interface Global {
globalBaseUrl: string;
}
}
}
}
// 全局可访问
window.isCloseHint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# JSX
- 可以做jsx文件内的类型声明
- 声明一个标签元素
declare namespace JSX {
interface IntrinsicElements {
foo: { bar?: boolean }
}
}
// `foo`的元素属性类型为`{bar?: boolean}`
<foo bar />;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8