如何在 Typescript 中类型检查二进制类型别名
How to type check a binary type alias in Typescript
我想根据参数的给定类型来确定条件,但由于所有可能的参数都是相同的二进制类型(数字),我正在寻找一种方法来创建某种类型别名,它可以被检查。
这是最初的想法,行不通,因为 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);
真实原因
JavaScript
JavaScript 以及其他任何编程语言,都带有一组原始值。因为 es6
是 Six
- 人数
- 字符串
- 布尔值
- 未定义
- 无
- 符号
如您所见,Percentage
不是其中之一。
您的 execution time we're in javascript land here
语句中可能正确的是类型 "do not exists on 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
和"Percentage" !== "number"
这就是为什么你总是进入 else 的原因。获得 instanceof
百分比的唯一方法是创建对象调用 Percentage:
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));
我想根据参数的给定类型来确定条件,但由于所有可能的参数都是相同的二进制类型(数字),我正在寻找一种方法来创建某种类型别名,它可以被检查。
这是最初的想法,行不通,因为 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);
真实原因
JavaScript
JavaScript 以及其他任何编程语言,都带有一组原始值。因为 es6
是 Six
- 人数
- 字符串
- 布尔值
- 未定义
- 无
- 符号
如您所见,Percentage
不是其中之一。
您的 execution time we're in javascript land here
语句中可能正确的是类型 "do not exists on 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
和"Percentage" !== "number"
这就是为什么你总是进入 else 的原因。获得 instanceof
百分比的唯一方法是创建对象调用 Percentage:
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));