如何在Typescript中检查二进制类型的别名。

问题描述 投票:0回答:1

我想把一个条件依赖于一个参数的给定类型,但是由于所有可能的参数都是相同的二进制类型(数字),我想寻找一种方法来创建某种类型的别名,可以进行检查。

这是最初的想法,但不可行,因为typescript被编译成javascript,因此 bonus 将永远是javascript类型 number.

    type Percentage = number;

    class Foo {
      applyBonus(bonus: Percentage | number) {
        if (typeof bonus === 'Percentage') {
          console.log('Percent');
        } else {
          // it's always number, because at execution time we're in javascript land here
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(6 as Percentage);

这个问题主要集中在typescript语言的可能性,以及是否可以用typescript的特性来解决这个问题。可以很容易地使用一个类似于 {value:6,type:'percent'} 而不是一个二进制类型的数字。

typescript design-patterns language-features type-alias
1个回答
2
投票

Typescript并不是根据事物的名称进行类型化,而是根据事物的结构进行类型化。你可以把一个数字命名为别的东西,但它仍然是一个数字。Percentage 这里只是一个别名。

更好的方法是创建一个具有独特形状的接口,你可以在运行时轻松识别。

interface Percentage { percentage: number }

class Foo {
   applyBonus(bonus: Percentage | number) {
      if (typeof bonus === 'object') {
         console.log('Percent', bonus.percentage);
      } else {
         console.log('number', bonus); 
      } 
   }
}

new Foo().applyBonus(123)
new Foo().applyBonus({ percentage: 456 })

游戏场


或者(我不推荐这样做,但在学术上很有趣),你可以将子类的 Number 并利用这一点。

class Percentage extends Number { }

class Foo {
   applyBonus(bonus: Percentage | number) {
      if (bonus instanceof Percentage) {
         console.log('Percent', bonus);
      } else {
         console.log('number', bonus); 
      } 
   }
}

new Foo().applyBonus(123)
new Foo().applyBonus(new Percentage(456))

但实际上,我会质疑你对这个的需求。我不知道你想达到什么目的,但可能有一个更简单的方法。


1
投票

代码示例

type Percentage = number;

    class Foo {
      applyBonus(bonus: Percentage | number) {
        if (typeof bonus === 'Percentage') {
          console.log('Percent');
        } else {
          // NO, IT IS NOT ALWAYS NUMBER BECAUSE OF THAT
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(6 as Percentage);

真正的原因

脚本语言

脚本语言 和其他任何编程语言一样,都有一组基元值。这是因为 es6

  • 数目
  • 绳子
  • 布尔型
  • 未定义
  • 无效
  • 符号

你可以注意到 Percentage 不是其中之一。

的东西,可以从你的 execution time we're in javascript land here 语句的事实是类型 "不存在于JS上"......不完全正确,因为类型确实存在于JS中,但你的例子中的编译代码看起来有些像这样

class Foo {
    applyBonus(bonus) {
      if (typeof bonus === 'Percentage') {
        console.log('Percent');
      } else {
        console.log('number'); 
      } 
    }
  }

  let bar = new Foo();
  bar.applyBonus(5);
  bar.applyBonus(6);

如果我们看 bar.applyBonus 你正在通过 5 n 6 这是两个基元值,因为它们都是数字。

如果你不相信我的话,打开浏览器的控制台,然后粘贴以下内容typeof 5

enter image description here

而 "百分比" !="数字"

这也是为什么你总能进入其他里面的原因。只有这样,你才能有一个 instanceof 百分比是通过创建一个对象调用百分比。

class Percentage {
  constructor (value) {
     this.value = value;
  }
}

 class Foo {
      applyBonus(bonus) {
        if (bonus instanceof === Percentage) {
          console.log('Percent');
        } else {
          // NO, IT IS NOT ALWAYS NUMBER BECAUSE OF THAT
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(new Percentage(6));
© www.soinside.com 2019 - 2024. All rights reserved.