我想把一个条件依赖于一个参数的给定类型,但是由于所有可能的参数都是相同的二进制类型(数字),我想寻找一种方法来创建某种类型的别名,可以进行检查。
这是最初的想法,但不可行,因为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并不是根据事物的名称进行类型化,而是根据事物的结构进行类型化。你可以把一个数字命名为别的东西,但它仍然是一个数字。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))
但实际上,我会质疑你对这个的需求。我不知道你想达到什么目的,但可能有一个更简单的方法。
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
而 "百分比" !="数字"
这也是为什么你总能进入其他里面的原因。只有这样,你才能有一个 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));