当前位置:   article > 正文

ts常用内置工具类型的使用说明_ts record

ts record

Record

源码

Record<key type, value type>
  • 1

Record是一个用于创建具有特定类型的键和值的对象类型的工具类型。它的语法是Record<K, V>,其中K是键的类型,V是值的类型

type Record<K extends string | number | symbol, T> = {
    [P in K]: T;
}
/**
 * 泛型K即为第一次参数
 * in的意思就是遍历,如上就是将 类型string进行遍历,也就是string
 * 每个属性都是传入的T类型
 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 使用案例一
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",
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这个例子中,我们使用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',
}
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这个例子中,我们定义了一个泛型函数createRecord,它接受一个键值数组keys和一个值value,然后使用Record来动态创建一个对象。我们使用Partial<Record<K, V>>来先创建一个部分记录,然后通过循环将每个键设置为指定的值,最后返回完整的记录

Partial

源码

type Partial<T> = {
  [P in keyof T]?: Partial<T[P]>
}
  • 1
  • 2
  • 3

Partial是ts官方提供的一个工具方法,生成一个新类型,该类型与T拥有相同的属性,但是所有属性皆为可选的

interface Todo {
  title: string;
  description: string;
  completed: boolean;
  date: Date;
}
type TodoPartial = Partial<Todo>;
function createApp(options: TodoPartial) {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码使TodoPartial的类型来源于Todo,但是将Todo中的每一个字段都变为可选的,如下图
在这里插入图片描述

Required

源码

type Required<T> = {
  [P in keyof T]-?: T[P];
};
  • 1
  • 2
  • 3

Required是ts官方提供的一个工具方法,生成一个新类型,该类型与T拥有相同的属性,但是所有属性皆为必填的

interface Todo {
  title?: string;
  description?: string;
  completed?: boolean;
  date?: Date;
}
type TodoPartial = Required<Todo>;
function createApp(options: TodoPartial) {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码使TodoPartial的类型来源于Todo,但是将Todo中的每一个字段都变为必填的,如下图
在这里插入图片描述

Readonly

源码

type Readonly<T> = {
  readonly [R in keyof T]: T[R];
};
  • 1
  • 2
  • 3

Readonly是ts官方提供的一个工具方法,生成一个新类型,T中的R属性是只读的,R属性是不可修改的。

interface UserInfo {
  name: string;
  age: number;
}
type Person = Readonly<UserInfo>;
// 相当于
type Person = {
  readonly name: string;
  readonly age: number;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Exclude

源码

type Exclude<T, U> = T extends U ? never : T
  • 1

Exclude是ts官方提供的一个工具方法,用于从类型T中排除可以赋值给类型U的所有类型,如果TU的子类型则返回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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Extract

源码

type Exclude<T, U> = T extends U ? never : T
  • 1

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Pick

源码

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
  • 1
  • 2
  • 3

Pick是ts官方提供的一个工具方法,它有两个参数,第一参数为类型,第二个参数为第一个类型中的字段,并且仅保留第二个参数传入的字段

interface Todo {
  title: string;
  description?: string;
  completed?: boolean;
  date: Date;
}
type TodoPick = Pick<Todo, "title" | "description" | "completed">;
function createApp(options: TodoPick) {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码使TodoPick的类型来源于Todo,但是仅保留了titledescriptioncompleted属性,如下图
在这里插入图片描述

Omit

源码

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
  • 1

Omit是ts官方提供的一个工具方法,它有两个参数,第一参数为类型,第二个参数为第一个类型中的字段,并且将第二个参数传入的字段过滤掉,与Pick相反

interface Todo {
  title?: string;
  description: string;
  completed: boolean;
  date: Date;
}
type TodoOmitted = Omit<Todo, "completed" | "date">;
function createApp(options: TodoOmitted) {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码使TodoOmitted的类型来源于Todo,但是过滤掉了completeddate这两个属性,如下图
在这里插入图片描述

NonNullable

NonNullable的作用是将给定类型中的nullundefined类型排除,从而得到一个新的类型,该类型被转换为非空类型。这个转换是通过类型推断和条件类型来实现的

NonNullable 是ts中的内置预定义工具类型,其源代码并不直接暴露给开发者。它是ts语言服务的一部分,并在编译过程中应用于类型检查和类型推断,下面是NonNullable的简化版本的伪代码示例,用于说明其原理

type NonNullable<T> = T extends null | undefined ? never : T;
  • 1

这段简化的伪代码表示,如果传入的类型Tnullundefined,则将其换成never类型,否则保持原来的类型T

type T = NonNullable<string | number | undefined | null>;
// 相当于
type T = string | number
  • 1
  • 2
  • 3

Parameters

Parameters的作用是以元组的方式获得函数的入参类型

Parameters 的源码并不直接暴露给开发者,因为它是ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了Parameters 的工作原理

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
  • 1

这段伪代码表示,如果传入的类型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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ConstructorParameters

ConstructorParameters作用:以元组的方式获得构造函数的入参类型

ConstructorParameters 的源码并不直接暴露给开发者,因为它是ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了ConstructorParameters 的工作原理

type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
  • 1

这段伪代码表示,如果传入的类型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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ReturnType

ReturnType 作用:获取函数类型的返回值类型,而不需要手动指定或提取

ReturnType 的源码并不直接暴露给开发者,因为它是 ts语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了ReturnType 的工作原理

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
  • 1

这段伪代码表示,如果传入的类型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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

InstanceType

InstanceType 作用:获得构造函数类型的实例类型

InstanceType 的源码并不直接暴露给开发者,因为它是 ts 语言服务的一部分,用于类型检查和类型推断。但我们可以推测其实现原理,下面是一个简化的伪代码示例,描述了InstanceType 的工作原理

type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
  • 1

这段伪代码表示,如果传入的类型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;
}
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
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);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的例子是我们使用vue3+ts+element-plus在实际开发中获取ref时的类型获取方式,见下图
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/545481
推荐阅读
相关标签
  

闽ICP备14008679号