typescript 中的 infer 关键字的理解
infer 这个关键字,整理记录一下,避免后面忘记了。有点难以理解呢。
infer
infer 是在 typescript 2.8
中新增的关键字。
infer
可以在 extends
条件类型的字句中,在真实分支中引用此推断类型变量,推断待推断的类型。
例如:用infer
推断函数的返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
type fn = () => number
type fnReturnType = ReturnType<fn> // number
在这个例子中,
T extends U ? X : Y
的形式为条件类型。
infer R
代表待推断的返回值类型,如果T
是一个函数(...args: any[]) => infer R
,则返回函数的返回值R
,否则返回any
案例:加深理解
反解 Promise
// promise 响应类型
type PromiseResType<T> = T extends Promise<infer R> ? R : T
// 验证
async function strPromise() {
return 'string promise'
}
interface Person {
name: string;
age: number;
}
async function personPromise() {
return {
name: 'p',
age: 12
} as Person
}
type StrPromise = ReturnType<typeof strPromise> // Promise<string>
// 反解
type StrPromiseRes = PromiseResType<StrPromise> // str
type PersonPromise = ReturnType<typeof personPromise> // Promise<Person>
// 反解
type PersonPromiseRes = PromiseResType<PersonPromise> // Person
反解函数入参类型
type Fn<A extends any[]> = (...args: A) => any
type FnArgs<T> = T extends Fn<infer A> ? A : any
function strFn (name: string) {
}
type StrFn = FnArgs<typeof strFn> // [string]
tuple 转 union ,如:[string, number] -> string | number
type ElementOf<T> = T extends Array<infer E> ? E : never
type TTuple = [string, number];
type ToUnion = ElementOf<ATuple>; // string | number
new 操作符
// 获取参数类型
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
// 获取实例类型
type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
class TestClass {
constructor(
public name: string,
public string: number
) {}
}
type Params = ConstructorParameters<typeof TestClass>; // [string, numbder]
type Instance = InstanceType<typeof TestClass>; // TestClass
react - reducer
// 定义
function useReducer<R extends Reducer<any, any>, I>(
reducer: R,
// ReducerState 推断类型
initializerArg: I & ReducerState<R>,
initializer: (arg: I & ReducerState<R>) => ReducerState<R>
): [ReducerState<R>, Dispatch<ReducerAction<R>>];
// infer推断
type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any>
? S
: never;
// Reducer类型
type Reducer<S, A> = (prevState: S, action: A) => S;
// 使用 reducer
const reducer = (x: number) => x + 1;
const [state, dispatch] = useReducer(reducer, '');
// Argument of type "" is not assignable to parameter of type 'number'.
vue3 - ref
export interface Ref<T = any> {
[isRefSymbol]: true
value: T
}
export function ref<T>(value: T): T extends Ref ? T : Ref<UnwrapRef<T>>
export type UnwrapRef<T> = {
cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
ref: T extends Ref<infer V> ? UnwrapRef<V> : T
array: T
object: { [K in keyof T]: UnwrapRef<T[K]> }
}[T extends ComputedRef<any>
? 'cRef'
: T extends Array<any>
? 'array'
: T extends Ref | Function | CollectionTypes | BaseTypes
? 'ref' // bail out on types that shouldn't be unwrapped
: T extends object ? 'object' : 'ref']
// 使用
const count = ref({
foo: ref('1'),
bar: ref(2)
})
// 推断出
const count: Ref<{
foo: string;
bar: number;
}>
const count = ref(2) // Ref<number>
const count = ref(ref(2)) // Ref<number>
参考
typescript 中的 infer 关键字的理解的更多相关文章
- TypeScript 中命名空间与模块的理解?区别?
一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...
- java中对final关键字的理解以及使用场景
谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.
- c++中的const关键字的理解
看effective c++第二版推荐使用const,少用define.今天才发现发现这远远不够. #define定义的常量在预处理替换,debug的时候无法打印宏的,这种常量设置是有缺陷的, con ...
- 白话typescript中的【extends】和【infer】(含vue3的UnwrapRef)
大家好,我是小雨小雨,致力于分享有趣的.实用的技术文章. 内容分为翻译和原创,如果有问题,欢迎随时评论或私信,希望和大家一起进步. 分享不易,希望能够得到大家的支持和关注. extends types ...
- TypeScript `infer` 关键字
考察如下类型: type PromiseType<T> = (args: any[]) => Promise<T>; 那么对于符合上面类型的一个方法,如何得知其 Prom ...
- 正确理解JavaScript中的this关键字
JavaScript有this关键字,this跟JavaScript的执行上下文密切相关,很多前端开发工程师至今对this关键字还是模棱两可,本文将结合代码讲解下JavaScript的this关键字. ...
- 深入理解java中的synchronized关键字
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...
- 转载 深入理解JavaScript中的this关键字
转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字 1. 一 ...
- 深入理解python中的yield关键字
想必大家都看过这样的代码: 上面的这段代码会计算0-9的平方并打印出来. 那么问题来了,这段代码和我们要说的东西有什么区别呢? 这里的关键字,yield,我在前面的文章里已经发过了.那么yield是什 ...
随机推荐
- Java中浮点数的坑
基本数据类型 浮点数存在误差 浮点数有一个需要特别注意的点就是浮点数是有误差的,比如以下这段代码你觉得输出的什么结果: public class Demo { public static void m ...
- ffmpeg实践
将mov视频解码300帧,并保存为1024:576分辨率,yuv420格式 ffmpeg -i Community_SneakAttack.mov -aspect 16:9 -vf scale=102 ...
- 调用免费API查询全年工作日、周末、法定节假日、节假日调休补班数据
前言 日常开发中,难免会用到判断今天是工作日.周末.法定节假日.节假日调休补班做一些业务处理,例如:仅在上班时间给用户推送消息.本文记录调用免费API查询全年工作日.周末.法定节假日.节假日调休补班数 ...
- 《Ray Tracing in One Weekend》阅读笔记 - 9、Metal(金属)
如果我们希望不同的物体使用不同的材料,则需要进行设计决策.我们可以使用具有许多参数的通用材料,而将不同的材料类型仅将其中一些参数归零.这不是一个坏方法.或者我们可以有一个抽象的材料类来封装行为.我是后 ...
- 字体:等宽字体与比例字体 - Monospaced font & Proportional font
字体:等宽字体与比例字体 - Monospaced font & Proportional font 量子波儿 2013-08-24 16:54:12 7101 收藏 1分类专栏: 计算机常识 ...
- 资源限制 ( resource limit 或 rlimit ),是 Linux 内核控制 用户 或 进程 资源占用的机制。
###### https://learn-linux.readthedocs.io/zh_CN/latest/administration/kernel/rlimit.html ########### ...
- Linux创建RAID概述
Linux创建RAID RAID概述 RAID(Redundant Array of Independent Disk)虚拟存储系统 RAID即独立冗余磁盘阵列,其思想是将多块独立的磁盘按不同的方式组 ...
- 010.Ansible_palybook 循环语句
Ansible循环语句 1 简介 我们在编写playbook的时候,不可避免的要执行一些重复性操作,比如指安装软件包,批量创建用户,操作某个目录下的所有文件等.正如我们所说,ansible一门简单的自 ...
- 10.12 telnet:远程登录主机
telnet命令 以前是用于登录远程主机,对远程主机进行管理的.但是因为telnet是采用明文传送报文的,其安全性不好,因此现在很多Linux服务器都不开放telnet服务,而是改用更安全的SSH服务 ...
- Python爬虫-Scrapy框架的工作原理
Scrapy框架工作原理 Scrapy框架架构图 Scrapy框架主要由六大组件组成,分别为: 调度器(Scheduler),下载器(Downler),爬虫(Spiders),中间件(Middwa ...