I would like to depend a condition on the given type of an argument, but since all possible arguments are the same binary type (number), I look for a way to create some kind of a type alias, that can be checked for.
This is the initial idea, that doesn't work, because typescript is compiled into javascript and thus bonus
will always be the javascript type 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);
This question is mainly focused on the possibilities of the typescript language, and if this can be solved with typescript features. It would be easily possible to use an object like {value:6,type:'percent'}
instead of a binary type number.
Typescript doesn't type based on the names of things, but the structure of thing. You can name a number something else, but it's still a number. Percentage
here is just an alias.
A better way to do something like this would be to create an interface with a unique shape that you could easily identify at runtime.
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 })
Alternatively (I don't recommend this, but is interesting academically), you could subclass Number
and use that.
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))
But really, I would question your need for this. I'm not sure what you are trying to accomplish here, but there is probably a simpler way.