0

I have a array of shadow styles that looks like this

const shadows = [
  'none',
  '0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)',
  "...And more"
];

My goal is to be able to use them safely in my JSS with intellisense, so I have this to accomplish that

type Enumerate<
  N extends number,
  Acc extends number[] = []
> = Acc['length'] extends N
  ? Acc[number]
  : Enumerate<N, [...Acc, Acc['length']]>;

export type IntRange<F extends number, T extends number> = Exclude<
  Enumerate<T>,
  Enumerate<F>
>;

export const shadow = (num: Shadow) => shadows[num];
// This will make it possible to only input numbers from 0 to 24
export type Shadow = IntRange<0, 24>;

And using them like this in my components boxShadow: theme.shadows(10) and this will throw a error if out of range.

Instead of hardcoding 24 as maximum is it possible to utilize the length of the array here? To have it be something like this export type Shadow = IntRange<0, shadows.length>;

2
  • Yes it is possible. Commented Oct 28, 2022 at 15:02
  • 1
    You'd have to declare the array as const shadows = [...] as const;. Even if an array is assigned to a const variable, you can still push to it at runtime. The as const after the array literal is how you tell TypeScript that it cannot change in any way. Commented Oct 28, 2022 at 15:05

1 Answer 1

2

If you make your shadows a tuple (shortcut with as const), then you can use the length property, as it will be a number literal type:

const shadows = [
  'none',
  '0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)',
  "...And more",
] as const; // now type is a readonly tuple of length 3

export type Shadow = IntRange<0, typeof shadows["length"]>; // OK

Playground (with 24 elements)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.