2

Looking at Is it possible to restrict number to a certain range I found the type for creating Ranges and Enumerates.

Looking at What is the type of an enum in Typescript? I found a type definition for passing Enums as values to functions.

Now: I'm writing a lil UI/UX library here at prudencss@github, my hobby project. Whilst doing so, playing around and trying to do things properly ... I was trying to introduce the following mechanism:

I wanted to create enums like:

export enum EInputInteractionState {
  Default = 0,
  Hover = 1,
  Focus = 2,
  Active = 4,
  Selected = 8,
}

Now, it would be possible and sometimes useful to have combinatoric states of the defined states as well, for example some list element could be:

  • hovered
  • selected at the same time. In order to be able to save all that data in one var/number, I define the initial keys/values as v = 0, 2^n ... (== 0, 1, 2, 4, 8, 16, ...) This would allow me to save every permutated combinatoric state as a number that is the sum of it's active defined states ... that number would always fill the gaps in between the quadratic row of numbers .... So basically though I define 5 states (= default state, plus 4 combinatoric states) in EInputInteractionState and define them as v = 0, 2^n, the overall combinatorically possible values would be the row symbolising the gaussian sum of v = 0, 1, 2, 3, ... n, ... (n * 2 - 1) = (n * (n + 1) /2)`.

Using the knowledge so far I do:

export const gaussianSum = <T extends Enum<T>>(E: T): number => {
  let length = Object.keys(E).filter(v => isNaN(v as unknown)).length;

  return length * (length + 1) / 2 + 1;
}

Now I wanted to finally and simply put a Prop into my React Components IProps of:

const permutationCount: number = gaussianSum(EInputInteractionState);

interface IProps {
  icon?: TIcon | TIcon[]
  state?: Enumerate<typeof permutationCount>,
}

However, if I simply put a concrete number the Enumarte type works quite well, but using this scenario I get TS2589 "Type instantiation is excessively deep and possibly infinite."

Is there a way to solve this issue???

Edit: typescript playground here: playground

Joehannes
  • 301
  • 2
  • 9
  • Why are you passing `EInputInteractionState` as the argument to your function? Your code is missing some types so I can't get it working in a sandbox. Please post a minimum working example to https://www.typescriptlang.org/play – jered Jan 05 '21 at 05:31
  • At any rate, while I understand how your proposed combinatoric state calculation is intended to work, I can't figure out WHY you would do such a thing. Seems unnecessarily abstract and overkill, unless your entire point is to play around with such a system, consider a different approach. – jered Jan 05 '21 at 05:37
  • I've added the playground in an edit @jered :) – Joehannes Jan 05 '21 at 05:56
  • Your problem is in `EnumerateInternal` type. You should wrap your recursion in some condition. – captain-yossarian from Ukraine Jan 05 '21 at 08:22

1 Answers1

0

For instance, you can start with updating your EnumerateInternal type:

type EnumerateInternal<A extends Array<unknown>, N extends number> = N extends A['length'] ? A : EnumerateInternal<PrependNextNum<A>, N>

But it might be not the case.

Your Enumerate type util should accept only literal numbers.

For instance, if you write:

type Result = Enumerate<10>

It would work.

It would work also for Enumerate<43>, but nor for 44.

But why only to 43?

Because it will produce numbers from 0 to 42 (meaning of the life)

So TS has some recursion limit.

If you want use return type of function, you should not write:

Enumerate<typeof gaussianSum>

Instead, you should write:

Enumerate<ReturnType<typeof gaussianSum>>

P.S. It is much safer to use Number.isNaN instead of isNaN

  • 1
    First: thx for the Number.isNaN hint!!! Second: nice joke! haha Main: Thx for the hint of Typescript having that recursion limit. I'm gonna wait if somebody comes up with something before I mark this answer as accepted :) Be aware, I'm not the TS Guru who wrote those type definitions, they are from the stackoverflow-questions mentioned at the beginning of the question. I guess I'm stuck on my own :) – Joehannes Jan 05 '21 at 11:43
  • @Joehannes sure, no problem )) Maybe smbd comes up with better explanation and solution. Will be happy to read it either – captain-yossarian from Ukraine Jan 05 '21 at 12:12