理解不太深,如果有不对的地方,欢迎指出,一起学习
ts-type-challenges 这里是 TS 体操类型挑战的题解,目前还没有做完
操作符
typeof:获取变量的声明或者类型
const v1 = 1234
const v2 = 'string'
const v3 = {
p: 123
}
const v4 = [1, 2, 3, 4]
type t1 = typeof v1 // type t1 = 1234
type t2 = typeof v2 // type t2 = "string"
type t3 = typeof v3
// type t3 = {
// p: number;
// }
type t4 = typeof v4 // type t4 = number[]
keyof:获取某种类型的所有 key 值,并返回联合类型
const v = {
p: 123,
p1: 'string'
}
type t = keyof typeof v // type t = "p" | "p1"
extends:泛型约束。还可以理解为遍历操作等
type v = 123 | 'string' | 456
type p = v extends number | string ? true : false // type p = true
// v extends number | string
// 可以理解为
// 123 extends number | string
// 'string' extends number | string
as:断言。目前主要用于属性 key 值的逻辑处理
// type-challenges - 8
// 实现一个通用 MyReadonly2<T, K>,它带有两种类型的参数 T 和 K。
// K 指定应设置为 Readonly 的 T 的属性集。如果未提供 K,则应使所有属性都变为只读,就像普通的 Readonly<T> 一样
type MyReadonly2<T, K extends keyof T = keyof T> =
{
readonly [P in keyof T]: T[P]
} & {
// 这里理解为:如果 P 在 K 的约束类型内则返回 never,否则返回 P。
// 返回 never 则表示在当前类型内剔除 P
[P in keyof T as P extends K ? never : P]: T[P]
}
in:用来遍历枚举类型
infer:声明一个类型变量
type f = (...args: any) => string
type Parameter<T extends (...args: any) => any> =
// 这里的 infer R 表示在当前环境中声明一个类型变量 R,用于后续逻辑的操作
T extends (...args: any) => infer R ? R : never
type r = Parameter<f> // type r = string
内置类型工具
在 ts 的开发中,如果熟悉内置的已有的工具类型,还是能极大的提升开发效率,也使类型更加规范。
Awaited
说明:递归地解开 awaited 类型。如果 then 不可调用则返回 never。模拟 await 的行为。
type Awaited<T> =
T extends null | undefined ? T :
T extends object & { then(onfulfilled: infer F): any }
? F extends ((value: infer V, ...args: any) => any)
? Awaited<V>
: never
: T;
示例:
type promise = Promise<Promise<number>>
type P1 = Awaited<promise>
// p1 === number
Partial
说明:使类型 T 中的所有属性都变为可选的。
type Partial<T> = {
[P in keyof T]?: T[P];
}
示例:
type t1 = {
num: number
age: number
name: string
}
type t2 = Partial<t1>
// type t2 = {
// num?: number | undefined
// age?: number | undefined
// name?: string | undefined
// }
Required
说明:使 T 中的所有属性都是必需的。
这里 - 的意思可以理解为取反, -? 是必填, -readonly 是可写
type Required<T> = {
[P in keyof T]-?: T[P];
}
示例:
type t1 = {
num?: number
age?: number
name: string
}
type t2 = Required<t1>
// type t2 = {
// num: number
// age: number
// name: string
// }
Readonly
说明:使 T 中的所有属性为只读
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
示例:
type t1 = {
num?: number
age?: number
name: string
}
type t2 = Readonly<t1>
// type t2 = {
// readonly num?: number | undefined;
// readonly age?: number | undefined;
// readonly name: string;
// }
Pick
说明:从 T 中,把集合 K 中的属性重新组装成一个新的类型。
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
示例:
type t1 = {
num?: number
age?: number
name: string
}
type t2 = 'num' | 'name'
type t3 = Pick<t1, t2>
// type t3 = {
// num?: number | undefined;
// name: string;
// }
Record
说明:构造一个具有类型 T 的属性集 K 的类型。
type Record<K extends keyof any, T> = {
[P in K]: T;
};
示例:
type t1 = 'num' | 'age' | 'name'
type t2 = Record<t1, number>
// type t2 = {
// num: number;
// age: number;
// name: number;
// }
Exclude
说明:从 T 中排除集合 U 的类型并返回一个新的类型集合。
type Exclude<T, U> = T extends U ? never : T;
示例:
type t1 = 'num' | 'age' | 'name'
type t2 = Exclude<t1, 'num'>
// type t2 = "age" | "name"
Extract
说明:从 T 中提取那些可分配给 U 的类型。与 Exclude 相反。
type Extract<T, U> = T extends U ? T : never;
示例:
type t1 = 'num' | 'age' | 'name'
type t2 = Extract<t1, 'num'>
// type t2 = "num"
Omit
说明:构造一个除类型 K 中的属性外具有 T 属性的类型。
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
示例:
type t1 = {
num?: number
age?: number
name: string
}
type t2 = Omit<t1, 'num'>
// type t2 = {
// age?: number | undefined;
// name: string;
// }
NonNullable
说明:从 T 中排除 null 和 undefined。
type NonNullable<T> = T extends null | undefined ? never : T;
示例:
type t1 = 'num' | 'age' | 'name' | null | undefined
type t2 = NonNullable<t1>
// type t2 = "num" | "age" | "name"
Parameters
说明:获取函数类型的参数。
type Parameters<T extends (...args: any) => any> =
T extends (...args: infer P) => any ? P : never;
示例:
type t1 = (value: number, name: string) => void
type t2 = Parameters<t1>
// type t2 = [value: number, name: string]
ConstructorParameters
说明:获取构造函数类型的参数。
type ConstructorParameters<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: infer P) => any ? P : never;
示例:
type t1 = new (v: string) => void
type t2 = ConstructorParameters<t1>
// type t2 = [v: string]
ReturnType
说明:获取函数类型的返回类型。
type ReturnType<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : any;
示例:
type t1 = (value: number, name: string) => string
type t2 = ReturnType<t1>
// type t2 = string
InstanceType
说明:获取构造函数类型的返回类型。
type InstanceType<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: any) => infer R ? R : any;
示例:
type t1 = new (v: string) => string
type t2 = InstanceType<t1>
// type t2 = string
Uppercase
说明:将字符串转为为大写。intrinsic 表示为可能目前的 ts 语法不好直接实现,直接用 intrinsic 标识为内置实现。
type Uppercase<S extends string> = intrinsic;
示例:
type t1 = 'value'
type t2 = Uppercase<t1>
// type t2 = "VALUE"
Lowercase
说明:将字符串转为为小写。intrinsic 表示为可能目前的 ts 语法不好直接实现,直接用 intrinsic 标识为内置实现。
type Lowercase<S extends string> = intrinsic;
示例:
type t1 = 'VALUE'
type t2 = Lowercase<t1>
// type t2 = "value"
Capitalize
说明:将字符串字面值类型的第一个字符转换为大写。intrinsic 表示为可能目前的 ts 语法不好直接实现,直接用 intrinsic 标识为内置实现。
type Capitalize<S extends string> = intrinsic;
示例:
type t1 = 'value'
type t2 = Capitalize<t1>
// type t2 = "Value"
Uncapitalize
说明:将字符串字面量类型的第一个字符转换为小写。intrinsic 表示为可能目前的 ts 语法不好直接实现,直接用 intrinsic 标识为内置实现。
type Uncapitalize<S extends string> = intrinsic;
示例:
type t1 = 'VALUE'
type t2 = Uncapitalize<t1>
// type t2 = "vALUE"
自定义工具类型
Merge
说明:将两个类型合并成一个类型,第二个类型的键会覆盖第一个类型的键。
type Merge<F, S> = {
[K in (keyof F | keyof S)]:
K extends keyof S ? S[K] : K extends keyof F ? F[K] : never
}
示例:
type t1 = {
age?: number
name: string
}
type t2 = {
num?: number
age?: string
}
type t3 = Merge<t1, t2>
// type t3 = {
// age: string | undefined;
// name: string;
// num: number | undefined;
// }
后续慢慢收集其它有用的工具类型...