【问题标题】:TS2322: Type '"Friendly"' is not assignable to type 'SoftSkillsEnum'TS2322:类型 '"Friendly"' 不可分配给类型 'SoftSkillsEnum'
【发布时间】:2020-12-27 09:26:12
【问题描述】:

我正在尝试实现一个由字符串组成的 Enum,以使我的代码更加健壮。

方法addSkills() 接收(以及其他)一个字符串数组的技能参数。

这里是测试代码:

    it('should record skills into database', async () => {
      const id = '19'
      const token = 'a64a47cc4c3c6282c229df78aab373c3d0dd94c4'
      const newSkill = 'Friendly'
      await service.addSkills(id, token, [newSkill])
      const recordedSkills = service.getCandidateSkills(id)
      expect(recordedSkills).toContain('Friendly')
    })
  })

这里是临时生产代码:

async addSkills(
    id: string,
    token: string,
    skills: SoftSkillsEnum[]
  ): Promise<[] | null> {
    throw new HttpException('Unknown resource', HttpStatus.NOT_FOUND)
  }

export enum SoftSkillsEnum {
  CREATIVE = 'Creative',
  FUNNY = 'Funny',
  EMPATHETIC = 'Empathetic',
  EXPLORER = 'Explorer',
  SPORTY = 'Sporty',
  SUPER_SMART = 'Super Smart',
  FRIENDLY = 'Friendly',
}

测试代码在测试代码的第 5 行触发了 Typescript 错误: TS2322: Type '"Friendly"' is not assignable to type 'SoftSkillsEnum'.

据我了解,Typescript 区分了字符串和由字符串组成的枚举。但我不希望我的方法接受任何字符串,输入应该匹配预定义的字符串列表(预定义的“softsSkills”)。

无论如何要让它工作还是我必须放弃我的枚举实现尝试?

【问题讨论】:

    标签: string typescript enums


    【解决方案1】:

    不确定为什么要使用枚举,但如果要将 skills 限制为字符串的子集,可以使用联合类型,例如

    export type SoftSkills = 'Creative' | 'Funny' | ... | 'Friendly';
    
    ...
    
    async addSkills(
        id: string,
        token: string,
        skills: SoftSkills[]
      ): Promise<[] | null> {
        throw new HttpException('Unknown resource', HttpStatus.NOT_FOUND)
      }
    
    
        it('should record skills into database', async () => {
          const id = '19'
          const token = 'a64a47cc4c3c6282c229df78aab373c3d0dd94c4'
          const newSkill = 'Friendly'
          await service.addSkills(id, token, [newSkill])
          const recordedSkills = service.getCandidateSkills(id)
          expect(recordedSkills).toContain('')
        })
    

    如果您需要运行时访问列表(例如用于验证),或者您确定需要枚举,则可以获取枚举的键:

    type SoftSkills = keyof(typeof SoftSkillsEnum);
    
    ...
    
    async addSkills(
        id: string,
        token: string,
        skills: SoftSkills[]
      ): Promise<[] | null> {
        throw new HttpException('Unknown resource', HttpStatus.NOT_FOUND)
      }
    
    
        it('should record skills into database', async () => {
          const id = '19'
          const token = 'a64a47cc4c3c6282c229df78aab373c3d0dd94c4'
          const newSkill = 'FRIENDLY'
          await service.addSkills(id, token, [newSkill])
          const recordedSkills = service.getCandidateSkills(id)
          expect(recordedSkills).toContain('')
        })
    

    但请注意,现在SoftSkills 是一个全部大写的技能列表,因为这是定义枚举的方式。

    或者也许只是实际将枚举用于您的newSkill

    ...
          const newSkill = SoftSkillsEnum.FRIENDLY
          await service.addSkills(id, token, [newSkill])
    ...
    

    【讨论】:

    • 非常感谢您提供的这个内容丰富的答案。但是枚举的目的之一不是“将技能限制为字符串的子集”(例如)吗?
    • 来自 TypeScript 文档本身:“枚举允许开发人员定义一组命名常量。使用枚举可以更容易记录意图,或创建一组不同的案例。”它引入了关于我应该使用什么。我很高兴有你的想法。
    • 我选择了类型联合而不是枚举。谢谢。
    • @AMehmeto 我会说枚举定义了“选项”集,不一定是字符串。我添加了一个直接使用枚举的建议,但是如果 newSkill 是一些用户输入(它是一个字符串),那将不会真正起作用。我主要将 enum 用于“命名常量”的目的,例如LEFT = 0b1, RIGHT = 0b10 等等,如果没有上下文,数字本身真的很难理解。这是我发现对这个主题有用的帖子:stackoverflow.com/a/40279394
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2017-04-10
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多