TypeScript 类型体操之 Push、Unshift、Parameters、Get Return Type

这期是比较简单的几道题:

1、Push

在类型系统里实现通用的 Array.push,例如:

ts 复制代码
type Result = Push<[1, 2], '3'> // [1, 2, '3']

新手注意,这里的 1, 2 和 '3' 是类型,而不是值! 我们通过泛型和类型推断来实现一个类型级别(type-level)的 Array.push 操作。

实现:

typescript 复制代码
type Push<T extends unknown[], U> = [...T, U];

// 使用示例
type OriginalArray = [1, 2, 3];
type ExtendedArray = Push<OriginalArray, 4>; // [1, 2, 3, 4]

Push 类型接受两个泛型参数 T 和 U。T 必须是一个数组类型,而 U 可以是任意类型。Push 的结果是一个新的数组类型,它通过展开原始数组类型 T 并在末尾添加类型 U 来构造。

这里使用了 TypeScript 的扩展运算符(...)来复制数组中的所有现有元素类型,并将新元素类型 U 添加到数组末尾。

再次说明:这个 Push 类型只是在类型层面上模拟了数组的 push 方法,它不会改变运行时的数组实例。在 TypeScript 中,类型层面的操作仅用于编译时的类型检查和推导,不会影响编译后的 JavaScript 代码的执行。

2、Unshift

实现类型版本的 Array.unshift。

例如:

ts 复制代码
type Result = Unshift<[1, 2], 0> // [0, 1, 2,]

和 Push 一模一样的思路,不再解释:

ts 复制代码
type Unshift<T extends unknown[], U> = [U, ...T]

3、Parameters

实现内置的 Parameters 类型,而不是直接使用它,可参考TypeScript官方文档。

例如:

ts 复制代码
const foo = (arg1: string, arg2: number): void => {}

type FunctionParamsType = MyParameters<typeof foo> // [arg1: string, arg2: number]

在 TypeScript 中,内置的 Parameters 类型用于提取函数类型的参数类型,并将它们作为一个元组类型返回。如果我们完整学习了前面的题目,应该首先想到使用 infer 来实现。

在 TypeScript 中,infer 关键字用于在条件类型表达式中进行类型推断。infer 关键字通常与 extends 关键字一起使用,它允许你在条件类型的 extends 后面的语句中声明一个类型变量,并对该类型变量进行操作。这样,你可以捕获并使用在类型关系测试中推断出的类型。

实现如下:

typescript 复制代码
type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

// 使用示例
function exampleFunction(a: string, b: number, c: boolean): void {}

type Params = MyParameters<typeof exampleFunction>; // [string, number, boolean]

MyParameters 类型接受一个泛型参数 T,它被约束为一个函数类型。然后,它使用条件类型来检查 T 是否可以赋值给一个具有参数 args 的函数类型,并使用 infer P 来推断 args 的类型。如果 T 是一个函数类型,MyParameters<T> 就会解析为参数的元组类型 P。如果 T 不是一个函数类型,结果就是 never。

4、Get Return Type

不使用 ReturnType 实现 TypeScript 的 ReturnType<T> 泛型。

ReturnType 用于获取函数的返回类型,实现思路同 Parameters,具体如下:

ts 复制代码
type MyReturnType<T extedns (...args: any) => any> = T extends (...args: any) => infer R ? R : never;

总结

这四道题没有什么新的知识点,复习了类型的扩展运算符和 infer 的使用。

相关推荐
肖永威16 分钟前
python版微电网仿真工具的前端托管选型:从http.server到FastAPI StaticFiles
前端·python·http·fastapi
风骏时光牛马16 分钟前
AI插件开发与效能提效工具箱
前端
IT_陈寒19 分钟前
为什么你应该学习Java?
前端·人工智能·后端
weixin_4173968339 分钟前
监控画面卡顿与录像缺失:码率、NVR与存储容量的排查顺序
前端·网络·技术·酒店·综合布线·弱电
曹牧1 小时前
Eclipse 工作空间(Workspace)的默认 JDK 配置
前端
其实防守也摸鱼2 小时前
Cylab在线靶场——挑战图书馆初学者指南
服务器·前端·数据库·chrome·安全·网络安全·靶场
拆房老料4 小时前
【第四部分:Agentic 智能体设计模式】16. 一个 Prompt 搞不定复杂任务?试试 Prompt Chaining
java·前端·人工智能·设计模式·prompt
曹牧9 小时前
C#:空合并运算符
java·前端·数据库
小羊没烦恼!10 小时前
铁道部新客票系统设计(二)
开发语言·前端·数据库·python·oracle·c#·php
智能直播13 小时前
RK3518:1.5G 内存 + 8G 存储,如何跑起硬件编解码、Web、AI 识别、绿幕特效
前端·人工智能·5g