1. Awaited
作用: 获取Promise中的类型(如await、then方法返回的被Promise包裹的数据的类型)。适合处理异步操作并确保解析值的类型安全。
使用
type A = Awaited<Promise<string>>; // string
type B = Awaited<Promise<Promise<number>>>; // number
// 假如这是一个第三方库,User没有导出,fetchUser函数导出了
interface User {
name: string
age: number
}
export async function fetchUser(): Promise<User> {
const data = await fetch('https://www.example.com/user').then(res => {
return res.json()
})
return data
}
// 我们开发中在获取到了User类型
type UserFetch = Awaited<ReturnType<typeof fetchUser>>
async function getUserInfo() {
let user: UserFetch = { name: 'x', age: 30 }
return user
}
源码实现
* Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`.
*/
type Awaited<T> = T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F, ...args: infer _): any; } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
F extends ((value: infer V, ...args: infer _) => any) ? // if the argument to `then` is callable, extracts the first argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T; // non-object or non-thenable
2. ConstructorParameters
作用: 接受一个具有构造函数的类型, 将构造函数的参数处理成一个元组类型。
使用
class Test { constructor(a: number, b: string) {}}
type T1 = ConstructorParameters<typeof Test>; // [a: number, b: string]
type T2 = ConstructorParameters<new (x: string, y: number) => any> // [x: string, y: number]
源码实现
/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
3. InstanceType
作用: 获取构造函数类型的返回类型(构造函数返回什么什么类型,InstanceType获取的就是什么类型)。
使用
class Person {
constructor(public name: string) {}
}
type PersonInstance = InstanceType<typeof Person>
const person: PersonInstance = new Person('Alice')
interface User {
new (name: string): Object
}
type UserInstance = InstanceType<User> // Object
源码实现
/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
4. ThisType
作用: 控制字面量对象中this所表示的类型。 只在--noImplicitThis下有用
使用
// 正常情况推导出来的this
type Point = {
x: number;
y: number;
moveBy(dx: number, dy: number): void;
}
let p: Point = {
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx; // this has type Point
this.y += dy; // this has type Point
}
}
// 使用ThisType进行控制this
type Point = {
x: number;
y: number;
moveBy(dx: number, dy: number): void;
}
let p: ThisType<{x: number}> & Point = {
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx; // this has type Point
this.y += dy; // error ❗️类型“{ x: number; }”上不存在属性“y”。
}
}
源码实现
interface ThisType<T> {}
扩展:
对象字面值方法中的表达式this的类型按照下面的方法进行确定:
- 如果方法具有显式声明的this参数,则this具有该参数的类型。
- 如果方法带了this参数,那么this就是这个。
- 如果对象字面量有
ThisType<T>的上下文类型,则该类型为T。 - 如果不包含,那么就自动推导
- 否则,
this就是any
5. ThisParameterType
作用: 提取函数类型的this参数的类型, 如果函数类型没有this参数, 返回unknown。
使用
function toHex(this: Number) {
return this.toString(16);
}
function numberToString(n: ThisParameterType<typeof toHex>) {
return toHex.apply(n);
}
源码实现
type ThisParameterType<T> = T extends (this: infer U, ...args: never) => any ? U : unknown;
6. OmitThisParameter
作用: 与ThisParameterType相反, 排除函数类型的this参数
使用
function toHex(this: Number) {
return this.toString(16);
}
const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(5);
console.log(fiveToHex());
源码实现
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;
7.NoInfer
作用: 阻止对所包含类型的推断。除了阻止推断之外,NoInfer<Type> 与 Type 相同。
使用
function createStreetLight<C extends string>(
colors: C[],
defaultColor?: NoInfer<C>,
) {
// ...
}
createStreetLight(["red", "yellow", "green"], "red"); // OK
createStreetLight(["red", "yellow", "green"], "blue"); // Error
源码实现
type NoInfer<T> = intrinsic
8. Uppercase
作用: 将字符串中的每个字符转换为对应的大写。
使用
type Greeting = 'Hello, world'
type ShoutyGreeting = Uppercase<Greeting> // "HELLO, WORLD"
type ASCIICacheKey<Str extends string> = `ID-${Uppercase<Str>}`
type MainID = ASCIICacheKey<'my_app'> // "ID-MY_APP"
源码实现
type Uppercase<S extends string> = intrinsic;
9. Lowercase
作用: 将字符串中的每个字符转换为对应的小写。
使用
type Greeting = 'Hello, world'
type QuietGreeting = Lowercase<Greeting> // "hello, world"
type ASCIICacheKey<Str extends string> = `id-${Lowercase<Str>}`
type MainID = ASCIICacheKey<'MY_APP'> // "id-my_app"
源码实现
type Lowercase<S extends string> = intrinsic;
10.Capitalize
作用: 将字符串中的第一个字符转换为大写字母。
11. Uncapitalize
作用: 将字符串中的第一个字符转换为小写字母。