Reputation: 39158
type Year_type is range 1800 .. 2100;
subset Natural of Int where * ≥ 0;
Int $even where { $_ % 2 == 0 }
TS
type Natural = BigInteger /* hypothetical → */ where (n) => { return n >= 0 };
Upvotes: 2
Views: 56
Reputation: 5489
As far as I know, here isn't such a type of constraint or Range
and one solution by be creating a specific class implementing those constrains.
In addition to this the union types may help you with smaller ranges:
type EvenDigits = 0 | 2 | 4 | 6 | 8;
Upvotes: 1
Reputation: 328302
You can't, at least as of TS3.8.
There is an open suggestion, microsoft/TypeScript#15480 to support a ranged numeric type; if you want to see that happen you might want to go to that issue, give it a 👍, and maybe describe your use case if you think it's particularly compelling and not already accounted for.
For the "even number" type in one of your examples, you'd need something else entirely; probably as a prerequisite you'd need the compiler to be able to perform arithmetic at the type level, which it currently does not do. As usual, there's an existing open issue for that, microsoft/TypeScript#26382, but I don't know if that will ever seriously happen. Dependent types are great but I don't know if they will happen anytime soon in the language.
Until then the best you can do is make a nominal-like type and a user-defined type guard to allow values to be of the proper type. But all that's doing is forcing developers to perform a bunch of runtime tests every time they want to use your constrained type, since the compiler can't enforce or check it:
type EvenNumber = number & { ___isEven: true };
function isEven(x: number): x is EvenNumber {
return x % 2 == 0;
}
function divideByTwoEvenly(x: EvenNumber): number {
return x / 2;
}
const a = divideByTwoEvenly(100); // error! 100 is not an EvenNumber
const hundred = 100;
if (isEven(hundred)) {
const a = divideByTwoEvenly(hundred);
} else {
throw new Error("I'm SAD");
}
Not so great. Oh well, hope that helps; good luck!
Upvotes: 2