TypeScript-keyof 与 in 操作符

前言

keyof和in操作符的使用方式看着有些相像,其实有很大的不同,keyof一般对对象类型使用,表示获取对象中的属性名。而in用于对象类型的定义中,右边跟一个联合类型,用来"迭代"联合类型简化对象类型的声明。本章介绍keyof和in操作符的用法,同时记录两个相关的实战案例。

一、keyof操作符的使用

1.1 基本使用

我们如果需要获取对象类型中的属性名,通常需要使用keyof。如下图,key可以使用"name"和"age"进行赋值,但是不能用"sex",因为Person类型中没有定义sex属性。

1.2 对对象索引签名使用

如果对声明了索引签名的对象使用keyof,会直接返回索引签名中的类型:

需要注意的是,如果索引签名的类型是string,那么使用keyof推导出的类型是number|string,原因是js中,使用数字作为属性名会被转换成字符串,SomeType1 和 SomeType"1"是等价的。

1.3 对泛型对象使用

对泛型参数使用keyof时需要注意,在js中允许使用数字、字符串、和Symbol类型来作为属性名,因此对泛型类型和any类型使用keyof时,推导出的类型为string|number|symbol

如果确定了对象只有某个类型的属性名,可以使用Extract关键字将类型提取出来:

1.4 实战

商场做的会员等级分为C、B、A、S四个等级,用户购买之后根据出示的会员卡计算折扣

根据描述我们很容易能写出如下的式子,但是ts会提示discountStrategy有确定的属性名,传入string是不合法的。

这个时候就可以借助keyof来获取discountStrategy的属性名,并声明VIPLevel只属于这个属性名范围:

实现步骤如下:

  1. 我们首先用typeof discountStrategy来获取discountStrategy的类型
  2. 再用keyof获取该类型的所有属性名
  3. 使用extends约束泛型T的对象上需要有discountStrategy的类型对于的属性名
  4. 最后将泛型T赋值给VIPLevel参数

二、in操作符的使用

in操作符比较简单,一般用在对象类型的声明中, 右边跟一个联合类型。常用方法如下:

可以看到,使用了in关键字后,ts自动推断出了CarValue的属性名和类型,不需要我们手动写。

上一章的实战使用in操作符,我们可以进行如下的优化:

实现步骤如下:

  1. 我们首先定义一个VIPLevel联合类型,列举所有会员等级
  2. 再申明一个VIPDiscountStrategy对象类型,使用in操作符来统一定义这个对象的属性值
  3. 最后在calculate函数上将参数VIPLevel的类型声明成VIPLevel联合类型即可实现相同效果

三、综合实战

原题地址: 实现Pick关键字

具体实现:

scala 复制代码
type MyPick<T, K extends keyof T> = {
  [key in K]: T[key];
};

实现思路:

  1. 我们定义两个泛型参数T和K,其中约束K的类型扩展T的属性名
  2. 再用key in K: T[key]来取出Pick出来的属性名

使用示例:

相关推荐
福兮说9 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理10 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66610 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)10 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan11 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_12 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒12 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技12 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu13 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙13 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript