Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A range of numbers #123

Closed
DanMossa opened this issue Aug 19, 2020 · 7 comments
Closed

A range of numbers #123

DanMossa opened this issue Aug 19, 2020 · 7 comments
Labels
help wanted Extra attention is needed type addition

Comments

@DanMossa
Copy link

DanMossa commented Aug 19, 2020

Something built in like this
https://stackoverflow.com/questions/39494689/is-it-possible-to-restrict-number-to-a-certain-range

Instead of

interface Car {
  model: string,
  year: 1999|2000|2001|2002
}

It would be nice to be able to do

interface Car {
  model: string,
  year: NumberRange<1999, 2002>
}

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@sindresorhus
Copy link
Owner

sindresorhus commented Aug 19, 2020

I think we could do something like what's done here: microsoft/TypeScript#15480 (comment) (don't forget to 👍🏻 on that issue) But it would be limited to a range of 40. That should be enough for many use-cases though.

@sindresorhus sindresorhus changed the title Feature Request: A range of numbers A range of numbers Aug 19, 2020
@sindresorhus sindresorhus added the help wanted Extra attention is needed label Sep 10, 2021
@henryruhs
Copy link

henryruhs commented May 28, 2022

What about this, stolen from stackoverflow and modified to work properly:

type Enumerate<NUMBER extends number, ARRAY extends number[] = []> = ARRAY['length'] extends NUMBER
    ? ARRAY[number] : Enumerate<NUMBER, [ ...ARRAY, ARRAY['length'] ]>
export type Range<FROM extends number, TO extends number> = Exclude<Enumerate<TO>, Enumerate<FROM>> | TO;

Some testing:

const validOne: Range<0, 100> = 0;
const validTwo: Range<0, 100> = 100;
const invalidOne: Range<0, 100> = 101;
const invalidTwo: Range<0, 100> = -1;

// my IDE show a warning as of the recursive call
const invalidThree: Range<0, 1000> = 1001;

@sindresorhus
Copy link
Owner

Seems like it's now possible with TypeScript 4.8: https://twitter.com/anuraghazru/status/1573328100246822917

Nice work, @anuraghazra

@souporserious
Copy link

I came across this problem on reddit and then checked this library to see if there was a utility yet. Not sure if this can be expanded further, but it seems there's a way to bypass the excessive iterations error after 1000 using template literals, see here.

@tommy-mitchell
Copy link
Contributor

tommy-mitchell commented Mar 6, 2023

I’ve started working on implementing a solution similar to microsoft/TypeScript#15480 (comment), with options to control the step size, if the range is inclusive, and if the range should be a union instead of a tuple (using UnionToTuple). Should the name be Range, as in Range<Start, End, Options>?

Still trying to figure out how to infer End if only Start is set:

type FiveNumbers = Range<5>;
//=> [0, 1, 2, 3, 4]

I also think it would be worth adding a RangeUnion wrapper that is just a Range with the {asUnion: true} option set. It should probably be inclusive as well, as that seems to be a common use for the union type.

@sindresorhus
Copy link
Owner

Should the name be Range, as in Range<Start, End, Options>?

👍

@jd-solanki
Copy link

Another solution: https://stackoverflow.com/a/39495173/10796681

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed type addition
Projects
None yet
Development

No branches or pull requests

7 participants