首页 > 编程语言 >[转]TypeScript类型编程中的extends和infer示例解析

[转]TypeScript类型编程中的extends和infer示例解析

时间:2024-01-29 11:27:42浏览次数:26  
标签:TypeScript 示例 Res extends 类型 type infer FirstChar

转自; https://www.jb51.net/javascript/294261vgi.htm

 

TypeScript类型编程中的extends和infer示例解析

  −
目录

引文

在刚接触TypeScript的时候,使用最多的就是type和interface这两个关键字,用来声明类型,其实这样也基本满足日常需求。但是如果需要设计一些高级类型的话,那么仅仅用原来所掌握的TypeScript知识是无法满足需求的。

设计高级类型的话涉及到类型编程的知识点,而类型编程中有两个关键字非常重要,分别是extends和infer。

extends用来约束入参的类型以及进行条件判断,infer用来声明局部的类型变量。

extends

条件判断

我们举个简单的例子来说明

?
1 type isOne<T extends number> = T extends 1 ? true : false

 

我们单独看T extends 1 ? true : false这部分,这里和JavaScript中的三元表达式并无二致,但是有些同学不清楚其中extends表示的是什么含义。

T extends 1 ? true : false表示的含义其实就是传入的T类型是否能够赋值给字面量1这个类型,如果可以的话,就返回true,否则返回false

约束参数类型

继续使用上面的例子,我们单独看T extends number,这里extends的意思就是限制传入的T类型必须是number类型,否则报错。

为什么需要有这个限制?

因为我们是要判断类型T是否能够赋值给字面量类型1,但是如果传入的参数都不是number类型,那么就没必要做后续的条件判断了。

约束infer推导的局部变量类型

?
1 2 3 4 type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest]   ? `${FirstChar}`   : never; type Res = GetFirst<['1', '2', '3']>;

 

来看看报错信息,我们传入的参数类型限制为sting类型的数组,但是infer推导出来的类型实际上是unknown类型,所以导致类型不匹配。

解决办法有三种:

对FirstChar使用extends先做过滤

?
1 2 3 4 5 type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest] ? FirstChar extends string   ? `${FirstChar}`   : never : never;

 

FirstChar和string进行交叉运算

?
1 2 3 type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest] ? `${FirstChar & string}` : never;

 

使用infer extends做类型转换

?
1 2 3 4 5 6 type GetFirst<T extends string[]> = T extends [ infer FirstChar extends string, ...infer Rest ] ? `${FirstChar}` : never;

 

infer extends是在ts 4.7版本支持,低于这个版本无法使用。

类型转换

?
1 2 3 4 type StrToNum<T extends string> = T extends `${infer Num extends number}` ? Num : T type Res = StrToNum<"1"> // ts 4.7时,返回的结果是type Res = number // ts 4.8及以上, 返回的结果是type Res = 1

 

infer

还是拿例子来进行讲解,下面的例子是要提取Promise包裹的类型。

?
1 2 type PromiseValue<T extends Promise<unknown>> = T extends Promise<infer Value> ? Value : never type Res = PromiseValue<Promise<string>> // string

 

画个简单的图来描述下如何提取变量类型。

 注意:infer声明的局部变量,只能在条件语句为true的分支里面使用。

如果在false分之里面使用通过infer声明的局部变量,编译器会直接报错表示找不到这个变量。

组合使用

ReturnType

内置工具类型RetureType用于获取函数的返回值类型。

?
1 2 3 4 5 type MyReturnType<T extends (...args: any) => any>     = T extends (...args: any) => infer R         ? R         : any; type Res = MyReturnType<() => string> // type Res = string

 

Parameters

内置工具类型Parameters用于获取函数的参数类型。

?
1 2 3 4 5 type MyParameters<T extends (...args: any) => any>     = T extends (...args: infer P) => any         ? P         : never; type Res = MyParameters<(a: string, b: number) => void>  // type Res = [a: string, b: number]

   

标签:TypeScript,示例,Res,extends,类型,type,infer,FirstChar
From: https://www.cnblogs.com/xuejianxiyang/p/17994092

相关文章

  • [Typescript] Handle CommonJS import in Typescript
    Let'ssayweneedtousealibrarywithcommonJScode.classMelon{cutIntoSlices(){}}module.exports=MelonThenwewanttoimportthisinsideourTypescriptproject:import*asmelonNamespacefrom"./melon"//typescriptdoesn......
  • 基于Basic auth 的一个C# 示例
    最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,谁让客户的系统就是这样的呢。因为现在开发中绝大多数使用的是基于Bearer认证的。......
  • PARI/GP编程示例
    素材主要来自我在RosettaCode上贡献的PARI/GP代码目录default(realprecision,110)控制实数计算的有效位数default(parisize,"32M");增加PARI/GP申请的栈内存大小顺序结构、选择结构、循环结构for-loop中设置步长vector实现map操作格式化打印switch-casefor-eachonelist应该没有......
  • 无涯教程-Socket.IO - 聊天示例
    现在我们已经很熟悉Socket.IO,让我们编写一个聊天应用程序,可以在不同的聊天室中使用它进行聊天,我们将允许用户选择用户名,并允许他们使用他们聊天。因此,首先,让我们设置HTML文件以请求用户名-<!DOCTYPEhtml><html><head><title>HelloLearnfk</title></head><......
  • 无涯教程-Socket.IO - 应用示例
    创建一个名为app.js的文件,然后输入以下代码来设置快速应用程序-varapp=require('express')();varhttp=require('http').Server(app);app.get('/',function(req,res){res.sendfile('index.html');});http.listen(3000,function(){conso......
  • 类,对象--示例代码
    #include<iostream>usingnamespacestd;classBox{ private: doublelength; doublewidth; public: voidsetLength(doublelength); voidsetWidth(doublewidth); doublegetLength(); doublegetWidth(); doublegetArea(); };voidBox::setLength......
  • Golang 语言入门:基础语法与示例
    引言Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。自2009年推出以来,Go已经成为云计算、微服务、网络服务器等领域的热门选择。其设计哲学是简洁、快速和易于理解,这使得Go语言特别适合当今快速发展的软件行业。Go语言的基本语法......
  • go-zero开发入门-初始化cache.ClusterConf示例
    cache.ClusterConf的定义如下://CacheConfisanaliasofClusterConf.typeCacheConf=ClusterConftype( //AClusterConfistheconfigofaredisclusterthatusedascache. ClusterConf[]NodeConf //ANodeConfistheconfigofaredisnodethatuseda......
  • 使用命令行方式搭建uni-app + Vue3 + Typescript + Pinia + Vite + Tailwind CSS + uv
    使用命令行方式搭建uni-app+Vue3+Typescript+Pinia+Vite+TailwindCSS+uv-ui开发脚手架项目代码以上传至码云,项目地址:gitee.com/breezefaith…目录一、前言近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台......
  • Vue 3高级响应式数据探秘:原理、用法详解与实战示例!
     在Vue3中,数据的变化通过响应式系统来实现,该系统基于ES6的Proxy对象。Proxy对象允许拦截并自定义操作,因此Vue可以通过代理对象来实现对数据的监听和触发相应的操作。以下是Vue3中监测数据改变的原理、使用方法和步骤的详细描述,以及一个实例代码:原理:Vue3的响应式系统基于P......