【问题标题】:how to check my string is part of a union type如何检查我的字符串是联合类型的一部分
【发布时间】:2020-01-22 09:20:30
【问题描述】:

我有一个类型保护,它接受一个字符串,我想知道它是否是联合类型的一部分,但是如果我们在联合类型中添加新字符串,我不想通过添加新字符串来管理我的类型保护:

type GreatAnimal = 'Dog' | 'Cat'

function isGreatAnimal(pet: string): pet is GreatAnimal {
    return pet === 'Dog' || pet === 'Cat'; // Here I would prefer to do something like 'pet keyof GreatAnimal'
}

function Foo(animal:string){
    if (isGreatAnimal(animal)) {
        // do something

    }
    else {
        // do something else
    }
}

如果我在联合类型“GreatAnimal”中添加 Fish,我不想更新我的类型保护来管理 Fish。

我正在使用最后一个打字稿版本

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您不能以编程方式使用类型,因为它们不会存在于转译的 JavaScript 代码中。

    例如你的代码的第一部分

    type GreatAnimal = 'Dog' | 'Cat'
    
    function isGreatAnimal(pet: string): pet is GreatAnimal {
        return pet === 'Dog' || pet === 'Cat';
    }
    

    转译为

    function isGreatAnimal(pet) {
        return pet === 'Dog' || pet === 'Cat';
    }
    

    因此,您需要对GreatAnimals 进行一些编程引用,以便隐式检查它们。有很多方法可以做到这一点 - 一个例子是使用枚举(它被转换为普通对象):

    enum GreatAnimal {
      DOG = "Dog",
      CAT = "Cat"
    }
    
    function isGreatAnimal(pet: string): pet is GreatAnimal {
      return pet in Object.values(GreatAnimal);
    }
    
    function Foo(animal: string) {
      if (isGreatAnimal(animal)) {
        // do something
      } else {
        // do something else
      }
    }
    

    (请注意,此示例使用Object.values,它是 ES2017 的一部分。Internet Explorer 不支持它,而 node 从 v7 开始支持它)

    【讨论】:

      【解决方案2】:
      const GreatAnimalList = ['Dog', 'Cat', 'Fish'] as const; // TS3.4 syntax
      type GreatAnimal = typeof GreatAnimalList[number]; // 'Dog'|'Cat'|'Fish';
      
      function isGreatAnimal(pet: string): pet is GreatAnimal {
        // return GreatAnimalList.includes(pet)
        return GreatAnimalList.indexOf(pet as GreatAnimal) !== -1
      }
      
      function Foo(animal: string) {
        if (isGreatAnimal(animal)) {
          // do something
          console.log('isGreatAnimal true')
        }
        else {
          // do something else
          console.log('isGreatAnimal false')
        }
      }
      
      Foo('Dog');      // isGreatAnimal true
      Foo('Turtle');   // isGreatAnimal false
      

      明天如果你在GreatAnimalList中添加一个新的动物,它会被自动添加到联合类型GreatAnimal中。并且isGreatAnimal()函数不需要做任何改动。

      【讨论】:

      • 使用 Typescript 3.6.3(最新版本)的 GreatAnimalList 类型不存在包含
      • 检查this answer。如果您不想更改为 es2016,那么我已将我的答案更新为不使用Array.includes()
      • 它不适用于 indexof。我在打字稿游乐场网站上收到此错误:“字符串”类型的参数不可分配给“狗”类型的参数 | 《猫》 | “鱼”。
      • 这个语法怎么称呼:typeof GreatAnimalList[number];我了解您的示例中的作用,但我想查找有关它的文档以了解它的工作原理
      • 检查 this answerthis answer 以及其中的链接
      猜你喜欢
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 2020-07-17
      • 1970-01-01
      • 2014-06-21
      • 1970-01-01
      • 2020-02-24
      相关资源
      最近更新 更多