赞
踩
源码
Record<key type, value type>
Record
是一个用于创建具有特定类型的键和值的对象类型的工具类型。它的语法是Record<K, V>
,其中K
是键的类型,V
是值的类型
type Record<K extends string | number | symbol, T> = {
[P in K]: T;
}
/**
* 泛型K即为第一次参数
* in的意思就是遍历,如上就是将 类型string进行遍历,也就是string
* 每个属性都是传入的T类型
*/
type Weekday = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday";
type Time = string;
const officeHours: Record<Weekday, Time> = {
Monday: "9:00-18:00",
Tuesday: "9:00-18:00",
Wednesday: "9:00-18:00",
Thursday: "9:00-18:00",
Friday: "9:00-17:00",
};
在这个例子中,我们使用Record
创建了一个对象officeHours
,它的键是Weekday
类型,值是Time
类型
function createRecord<K extends string | number, V>(
keys: K[],
value: V,
): Record<K, V> {
const record: Partial<Record<K, V>> = {};
for (const key of keys) {
record[key] = value;
}
return record as Record<K, V>;
}
const fruits = createRecord(["apple", "banana", "orange"], "fruit");
console.log(fruits);
/*
输出:
{
apple: 'fruit',
banana: 'fruit',
orange: 'fruit',
}
*/
在这个例子中,我们定义了一个泛型函数createRecord
,它接受一个键值数组keys和一个值value,然后使用Record
来动态创建一个对象。我们使用Partial<Record<K, V>>
来先创建一个部分记录,然后通过循环将每个键设置为指定的值,最后返回完整的记录
源码
type Partial<T> = {
[P in keyof T]?: Partial<T[P]>
}
Partial
是ts官方提供的一个工具方法,生成一个新类型,该类型与T
拥有相同的属性,但是所有属性皆为可选的
interface Todo {
title: string;
description: string;
completed: boolean;
date: Date;
}
type TodoPartial = Partial<Todo>;
function createApp(options: TodoPartial) {}
上面的代码使TodoPartial
的类型来源于Todo
,但是将Todo
中的每一个字段都变为可选的,如下图
源码
type Required<T> = {
[P in keyof T]-?: T[P];
};
Required
是ts官方提供的一个工具方法,生成一个新类型,该类型与T
拥有相同的属性,但是所有属性皆为必填的
interface Todo {
title?: string;
description?: string;
completed?: boolean;
date?: Date;
}
type TodoPartial = Required<Todo>;
function createApp(options: TodoPartial) {}
上面的代码使TodoPartial
的类型来源于Todo
,但是将Todo
中的每一个字段都变为必填的,如下图
源码
type Readonly<T> = {
readonly [R in keyof T]: T[R];
};
Readonly
是ts官方提供的一个工具方法,生成一个新类型,T
中的R
属性是只读的,R
属性是不可修改的。
interface UserInfo {
name: string;
age: number;
}
type Person = Readonly<UserInfo>;
// 相当于
type Person = {
readonly name: string;
readonly age: number;
};
源码
type Exclude<T, U> = T extends U ? never : T
Exclude
是ts官方提供的一个工具方法,用于从类型T
中排除可以赋值给类型U
的所有类型,如果T
是U
的子类型则返回never
,不是则返回T
type A = number | string | boolean
type B = number | boolean
type Foo = Exclude<A, B>
// 相当于
type Foo = string
// -------------------------------
type C = number | string | boolean;
type D = symbol ;
type E = Exclude<C, D>;
// 相当于
type E = number | string | boolean
// -------------------------------
type F = number;
type H = number | string | boolean;
type I = Exclude<F, H>;
// 相当于
type I = never
源码
type Exclude<T, U> = T extends U ? never : T
Extract
是ts官方提供的一个工具方法,用于从类型T
中提取可以赋值给类型U
的所有类型,作用与Exclude
相反
type A = number | string | boolean;
type B = number | boolean;
type Foo = Extract<A, B>;
// 相当于
type Foo = number | boolean
// -------------------------------
type C = number | string | boolean;
type D = symbol;
type E = Extract<C, D>;
// 相当于
type E = never
源码
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Pick
是ts官方提供的一个工具方法,它有两个参数,第一参数为类型,第二个参数为第一个类型中的字段,并且仅保留第二个参数传入的字段
interface Todo {
title: string;
description?: string;
completed?: boolean;
date: Date;
}
type TodoPick = Pick<Todo, "title" | "description" | "completed">;
function createApp(options: TodoPick) {}
上面的代码使TodoPick
的类型来源于Todo
,但是仅保留了title
、description
、completed
属性,如下图
源码
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
Omit
是ts官方提供的一个工具方法,它有两个参数,第一参数为类型,第二个参数为第一个类型中的字段,并且将第二个参数传入的字段过滤掉,与Pick
相反
interface Todo {
title?: string;
description: string;
completed: boolean;
date: Date;
}
type TodoOmitted = Omit<Todo, "completed" | "date">;
function createApp(options: TodoOmitted) {}
上面的代码使TodoOmitted
的类型来源于Todo
,但是过滤掉了completed
和date
这两个属性,如下图
NonNullable
的作用是将给定类型中的null
和undefined
类型排除,从而得到一个新的类型,该类型被转换为非空类型。这个转换是通过类型推断和条件类型来实现的
NonNullable
是ts中的内置预定义工具类型,其源代码并不直接暴露给开发者。它是ts语言服务的一部分,并在编译过程中应用于类型检查和类型推断,下面是NonNullable
的简化版本的伪代码示例,用于说明其原理
type NonNullable<T> = T extends null | undefined ? never : T;
这段简化的伪代码表示,如果传入的类型T
是null
或undefined
,则将其换成never
类型,否则保持原来的类型T
type T = NonNullable<string | number | undefined | null>;
// 相当于
type T = string | number
Parameters
的作用是以元组的方式获得函数的入参类型
Parameters 的源码并不直接暴露给开发者,因为它是ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了Parameters 的工作原理
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
这段伪代码表示,如果传入的类型T
是一个函数类型,那么T
将被拆解为一个函数签名,其中...args
是参数列表,infer P
表示类型推断,我们将其赋值给P
。然后,我们返回P
,即参数类型列表。如果T
不是函数类型,则返回never
类型
type ExampleFunction = (name: string, age: number) => void;
type Params = Parameters<ExampleFunction>;
// Params 的类型为 [string, number]
// -------------------------------
type t = Parameters<(name: string) => any>;
// type t = [string]
type t2 = Parameters<((name: string) => any) | ((age: number) => any)>;
// type t2 = [string] | [number]
ConstructorParameters
作用:以元组的方式获得构造函数的入参类型
ConstructorParameters 的源码并不直接暴露给开发者,因为它是ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了ConstructorParameters 的工作原理
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
这段伪代码表示,如果传入的类型T
是一个构造函数类型,那么T
将被拆解为一个构造函数签名,其中...args
是参数列表,infer P
表示类型推断,我们将其赋值给P
。然后,我们返回P
,即参数类型列表。如果T
不是构造函数类型,则返回never
类型
class ExampleClass {
constructor(name: string, age: number) {}
}
type Params = ConstructorParameters<typeof ExampleClass>;
// Params 的类型为 [string, number]
// -------------------------------
type t = ConstructorParameters<(new (name: string) => any) | (new (age: number) => any)>;
// type t = [string] | [number]
ReturnType 作用:获取函数类型的返回值类型,而不需要手动指定或提取
ReturnType 的源码并不直接暴露给开发者,因为它是 ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了ReturnType 的工作原理
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
这段伪代码表示,如果传入的类型T
是一个函数类型,那么T
将被拆解为一个函数签名,其中...args
是参数列表,infer R
表示类型推断,我们将其赋值给R
。然后,我们返回R
,即返回值类型。如果T
不是函数类型,则返回any
类型
function exampleFunction(): string {
return "Hello, World!";
}
type Return = ReturnType<typeof exampleFunction>;
// Return 的类型为 string
// -------------------------------
type t = ReturnType<(name: string) => string | number>
// type t = string | number
InstanceType 作用:获得构造函数类型的实例类型
InstanceType 的源码并不直接暴露给开发者,因为它是 ts 语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了InstanceType 的工作原理
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
这段伪代码表示,如果传入的类型T
是一个构造函数类型,那么T
将被拆解为一个构造函数签名,其中...args
是参数列表,infer R
表示类型推断,我们将其赋值给R
。然后,我们返回R
,即实例类型。如果T
不是构造函数类型,则返回any
类型
class ExampleClass {
name: string;
constructor() {
this.name = "Example";
}
}
type Instance = InstanceType<typeof ExampleClass>;
// Instance 的类型为 ExampleClass
// -------------------------------
type t = InstanceType<new (name: string) => { name: string; age: number }>;
/*
type t = {
name: string;
age: number;
}
*/
import { ElPopover, ElSelect } from "element-plus";
import { ref, onMounted } from "vue";
const ElPopoverRef = ref<InstanceType<typeof ElPopover>>();
const ELSelectRef = ref<InstanceType<typeof ElSelect>>();
onMounted(() => {
console.log(ElPopoverRef.value);
console.log(ELSelectRef.value);
});
上面的例子是我们使用vue3+ts+element-plus在实际开发中获取ref时的类型获取方式,见下图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。