Description
Search Terms
array tuple const assertion literal index number
Suggestion, Use Cases, and Examples
I would like to infer the index type of a const
-asserted array to be that of its position in the array, rather than just number
(i.e. I want the literal number type). However, I can't seem to create a way to extract this into a type
, even though I know TypeScript is holding onto this information somewhere.
For example, this code follows my intuition:
const days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] as const;
/** "Mo" | "Tu" */
type FirstTwoDays = (typeof days)[1 | 2]
/** 7 */
type DaysCount = typeof days.length;
const impossibleDayIndex = 88;
/** Tuple type 'readonly [...]' of length '7' has no element at index '88' */
type CorrectlyErrors = (typeof days)[typeof impossibleDayIndex];
Yet here, index
is of type number
. Although this is understandable, given the signature of Array['forEach']
, it begs the question - how could I assert, as the as const
does, that index
should be of type 0 | 1 | 2 | 3 | 4 | 5 | 6
?
days.forEach((day, index) => {});
Likewise, how could I get this to "work"?
const indexTypeLost = days.indexOf('Tu')
/** number, rather than 2 */
type IndexTypeLost = typeof indexTypeLost
The closest I can get to achieving my desired type
is with
/** number | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "length" | "toString" | ... */
type IndicesOfDays = keyof typeof days;
but it's not perfect:
const convertIndexToDay = (index: IndicesOfDays) => days[index]
convertIndexToDay(impossibleDayIndex) // incorrectly does not throw an error
Checklist
My suggestion meets these guidelines:
- [?] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.