• typescript 实现enum枚举值定义为对象


    壹 ❀ 引

    最近因为有一些闲散时间,所以一直在做将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,只要我们属性定义错误,或者额外多添加属性,都能正确达到错误提示。其实到这里我们就已经达到了枚举值是对象字面量类型的效果了。

  • 相关阅读:
    Beta 冲刺 (5/7)
    Beta 冲刺 (4/7)
    Beta 冲刺 (3/7)
    软件产品案例分析(团队)
    Beta 冲刺 (2/7)
    Beta 冲刺 (1/7)
    BETA 版冲刺前准备
    Alpha事后诸葛(团队)
    设计模式——访问者模式
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/echolun/p/16266714.html
Copyright © 2020-2023  润新知