美文网首页
Typescript 枚举类型检查问题

Typescript 枚举类型检查问题

作者: 高级程序狗 | 来源:发表于2020-08-14 16:00 被阅读0次

    问题起源是一段代码没有达到预期效果:

    enum Weekday {
      Monday = 1,
      Tuesday,
      Wednesday,
      Thursday,
      Friday,
      Saturday,
      Sunday
    }
    //100 已经超过了Weekday范围(1 ~ 7),但是并没有报错
    const a: Weekday = 100;
    

    研究期间又发现了新问题:

    enum Position {
      TOP = "top",
      BOTTOM = "bottom",
    }
    //报错,不能将类型“"top"”分配给类型“Position”
    const b: Position =  "top";
    //报错,不能将类型“"top"”分配给类型“Position.TOP”。
    const c: Position.TOP =  "top";
    

    奇了怪了!难道 enum 不是这么用的?

    经过一番查找,发现这是一个历史原因。有大量issue(至少几十个吧)反馈 enum 的反人类设计,开发者回复此问题改造很大,暂时不会修改。

    I don't see this as enough to change our mind here; this would be a very large breaking change and would imply bifurcating flag and nonflag enums. See #17734, #21546, #11559, #15591, #8020, #18409, etc.

    后来在#32690中找到了一种解决方法:

    namespace MyEnum {
      export const Zero = 0;
      export type Zero = typeof Zero;
    
      export const One = 1;
      export type One = typeof One;
    }
    type MyEnum = typeof MyEnum[keyof typeof MyEnum];
    const foo: MyEnum.Zero = 0 // okay as expected
    const bar: MyEnum.Zero = 1 // error as expected
    

    试了一下确实可以解决问题,但是代码看的不是很明白,主要是 typeofkeyof,我查了一下文档:

    • typeof 用来获取一个变量的类型:
    interface Person {
      name: string;
      age: number;
    }
    const sem: Person = { name: "semlinker", age: 30 };
    type Sem = typeof sem; // type Sem = Person
    
    • keyof 用来获取某种类型的所有键
    interface Person {
      name: string;
      age: number;
    }
    type PersonProperties = keyof Person; //type PersonProperties = "name" | "age"
    

    有了基础知识,继续分析大佬的解决方法,拆解和注释如下:

    namespace MyEnum {
      export const Zero = 0;
      export type Zero = typeof Zero;
    
      export const One = 1;
      export type One = typeof One;
    }
    type A = keyof typeof MyEnum; // type A = "Zero" | "One"
    type MyEnum = typeof MyEnum[A]; // type MyEnum = 0 | 1
    
    const foo: MyEnum.Zero = 0 // okay as expected
    const bar: MyEnum.Zero = 1 // error as expected
    const coo: MyEnum = 3 // error as expected
    

    研究过程中,发现一些资料,建议阅读:
    https://www.cnblogs.com/lyraLee/p/12398208.html
    https://stackoverflow.com/questions/17380845/how-do-i-convert-a-string-to-enum-in-typescript
    https://jkchao.github.io/typescript-book-chinese/typings/enums.html#%E5%BC%80%E6%94%BE%E5%BC%8F%E6%9E%9A%E4%B8%BE

    相关文章

      网友评论

          本文标题:Typescript 枚举类型检查问题

          本文链接:https://www.haomeiwen.com/subject/ybzwdktx.html