壹 ❀ 引
最近因为有一些闲散时间,所以一直在做将
Class组件重构为
typescript + hooks组件的工作,结果今天就遇到一个有趣的问题。我们知道
react Class组件一般都会定义
Component.propTypes属性,目的在于限制组件
props类型以及某个属性是否必传等。结果在改写过程中,我发现有个属性它的定义是一个枚举:
// 枚举定义,这里借用了项目自己封装的枚举创建方法 const PaymentTypeEnum = createSimpleEnum({ SENIOR: { value: 'pro', type: 1, }, TRIAL: { value: 'trial', type: 2 }, FREE: { value: 'free', type: 0, }, PENDING: { value: 'pending', type: 3 } }); // props大概的定义,type的结构可能是 Component.propTypes = { type: PropTypes.oneOf(EnumHelper.enumValues(PaymentTypeEnum) }
这里的
type类型就表示属于
PaymentTypeEnum其一,它可能是
{value:'pro',type:1},也可能是
{value:'free',type:0},而
ts是自带枚举的,所以这里我需要将其修改为
ts的枚举,让其类型推断上也能满足枚举其一。
贰 ❀ 解决Enum枚举值不能是对象
我们知道
ts中的类型其实可以分为比较抽象的原始类型,以及较为具体的字面量类型,比如我希望变量
a的值一定是个字符串,这里就能用抽象的
string表示:
const a:string = '1';
此时
a的值就必须是个字符串。而有时候我们希望某个变量的值,是按照我们预设好的值其一,这里就可以用联合类型结合字面量类型来达到效果,比如:
type NameType = 'echo' | '听风是风' | '时间跳跃'; const user: NameType = 'echo';
此时
user就只能是
echo这三个值其一,这在我们日常开发中,当为组件预设了部分固定配置时将十分有用。
所以回到开头的问题,我现在就是希望
type的类型约束,是我定义的枚举定义四个对象中的某一个,但尴尬的是,
ts枚举值定义并不支持对象,这会直接导致报错,这里我们可以借用接口与枚举达到这个效果:
// 定义枚举 enum PaymentTypeEnum { SENIOR, TRIAL, FREE, PENDING, }; // 定义接口 interface PaymentType { [PaymentTypeEnum.SENIOR]: { value: 'pro'; type: 1; }; [PaymentTypeEnum.TRIAL]: { value: 'trial'; type: 2; }; [PaymentTypeEnum.FREE]: { value: 'free'; type: 0; }; [PaymentTypeEnum.PENDING]: { value: 'pending'; type: 3; }; } // 组件props接口定义 interface ComponentPropsType { type: PaymentType[PaymentTypeEnum] }
我们来做个试验验证下,比如我现在要定义
payment值为:
const payment: ComponentPropsType = { type: { value: 'pendings',// Type '"pendings"' is not assignable to type '"pro" | "trial" | "free" | "pending"'. type: 4 // Type '4' is not assignable to type '0 | 1 | 2 | 3'. } }
可以看到,不管是
value还是
type,只要我们属性定义错误,或者额外多添加属性,都能正确达到错误提示。其实到这里我们就已经达到了枚举值是对象字面量类型的效果了。
相关文章推荐
- 使用hadoop命令rcc生成Record 一个简单的方法来实现自己的定义writable对象
- 如何定义和实现新的GObject之对象构造和析构
- 为每个enum实例定义不同的方法实现
- C++:对象数组、对象动态申请和释放、类的定义和实现分开、this指针、常成员函数、时钟
- //21、定义一个分数类使得分数对象可以整体输入输出;实现分数类中的运算符重载(分子和分母均为整型)
- 【C++语言实现】【本科实验系列】编写程序在CirCle类中实现关系运算符(大于,小于,等于),实现按半径对Circle对象排序,自己定义类中所需成员。完成上述功能。
- 定义对象的索引器 以及 实现枚举接口IEnumerable
- 【面向对象程序设计常见面试题】如何定义和实现一个类的成员函数为回调函数?
- 创建Employee类,在类中定义三个属性:编号,姓名,年龄,然后在构造方法里初始化这三个属性,最后载实现接口中的定义的CompareTo方法,将对象按编号升序排列。根据已有的代码,补全程序。
- 14. JAVA 枚举(Enum、类集EnumMap&EnumSet 、实现接口、定义抽象方法) ----- 学习笔记
- Angular2中实现基于TypeScript的对象合并方法:extend()
- javascript实现与后端相同的枚举Enum对象
- 自定义对象的归档 //类只有实现 NSCoding 协议才具备归档功能 归档最好定义成宏,笔误好发现.
- 第七周上机任务三--实现一个复数类--通过模板类的技术手段,设计Complex,使实部和虚部的类型为定义对象时用的实际类型
- QuickCSharp框架开发(13)------定义一个IAuthenticationProvider接口、将实现了接口的实例化对象转换成接口
- 定义一个List集合并实例化对应的实现类对象。循环输入任意个整数,输入0结束输入循环,对集合中的数据进行从大到小的排序后输出
- Oracle数据库通过定义TYPE及Member对象来实现日志信息的分级管理 推荐
- C++接口定义,实现,继承接口类的子类,实例对象访问方法问题
- 1.定义复数(Complex)类。 要求: (1)复数有实部和虚部属性; (2)定义类的构造方法; (3)实现复数加减法并输出复数属性的值。 (4)重载toString方法,用于对象属性值的输出。
- js定义对象的两种方法以及js用call来实现类的继承