【问题标题】:Can I determine if a value matches a type alias?我可以确定一个值是否与类型别名匹配吗?
【发布时间】:2020-07-07 07:04:30
【问题描述】:

在 TypeScript 中,我可以确定一个值是否是/匹配类型别名吗?

假设我有这种类型:

export type Name = "Jane" | "John";

然后我想在其他地方检查某个用户输入是否属于Name 类型。像if (input instanceOf Name) 这样的东西是行不通的。

这可能吗?

【问题讨论】:

    标签: typescript type-alias


    【解决方案1】:

    您无法检查值是否与类型别名匹配。类型在运行时被擦除,因此任何运行时代码都不能依赖它们。

    如果您控制类型别名,我建议您创建一个数组来保存值,让 TS 为其推断类型,并从中派生联合。然后你可以检查一个值是否在数组中:

    const Name = ["Jane", "John"] as const
    export type Name = typeof Name[number];
    
    function isName(a: unknown): a is Name {
        return Name.indexOf(a as Name) != -1;
    }
    
    

    Playground Link

    【讨论】:

      【解决方案2】:

      到目前为止,我知道的唯一方法是从 const 数组生成类型别名,然后对照这个数组检查你的名字。

      const names = ["Jane", "John"] as const;
      type Name = typeof names[number];
      
      function isValidName(name: string): name is Name {
          return names.includes(<Name> name);
      }
      

      用法:

      const test: string = "John";
      if (isValidName(test)) {
          console.log(`${test} is a name`);
      }
      else {
          console.log(`${test} is not a name`);
      }
      

      我仍然不明白为什么 typescript 不能从类似的东西编译

      type Example = 'first' | 'second';
      const exampleValues = [typeof Example] as const;
      

      到

      const exampleValues = ['first', 'second'];
      

      AFAIK 的答案是“类型在运行时被擦除”,但是在运行时将类型别名编译为文字数组不需要类型信息。

      1. 不会产生任何开销
      2. 保留 javascript 的运行时行为
      3. 并且不提供额外的运行时功能

      这将允许开发人员在运行时通过在数组中查找值来验证字符串。

      如果有办法做到这一点,请告诉我。 正如我所展示的,你可以做相反的事情,从数组到类型别名,但是使用类型别名你可以过滤和组合类型,我有兴趣在编译时从类型别名转换为数组.

      【讨论】:

        【解决方案3】:

        TypeScript 是结构化类型语言。这意味着当您创建一个类型时,左边有一个名称,右边有运行时中的精确类型表示。这里没有像在名义类型系统中那样的额外魔法(类和枚举是例外)。

        这意味着为了检查某物是否具有这种类型,我们需要进行显式检查或编写一个辅助函数来检查它。

        function isName(a: unknown): a is Name {
          return a === "Jane" || a === "John";
        }
        

        也许看起来很麻烦,但总的来说如果你做联合类型,选项的数量应该是合理的。如果选项的数量真的很大,可能数据模型是错误的,我们应该重新考虑是否需要这样的联合。

        【讨论】:

          【解决方案4】:

          不,在运行时这些信息不存在,因此不能用于此类用例。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-30
            • 1970-01-01
            相关资源
            最近更新 更多