Is it feasible to establish a non-empty list within TypeScript's type system? While I am aware that it is possible to define a list with a specific number of elements, similar to a Tuple:
type TwoElementList = [number, number];
This approach is limited to lists of predetermined lengths.
I have been examining the renowned CIS 194 course on Haskell, which illustrates defining a non-empty list using its type system:
data NonEmptyList a = NEL a [a]
My understanding is that achieving this in TypeScript might not be viable; however, I am curious if anyone can verify this.
In the section of CIS 914 that defines NonEmptyList
, we encounter conversions between this 'interface' and that of a regular list:
nelToList :: NonEmptyList a -> [a]
nelToList (NEL x xs) = x:xs
listToNel :: [a] -> Maybe (NonEmptyList a)
listToNel [] = Nothing
listToNel (x:xs) = Just $ NEL x xs
So as highlighted by @JeffreyWesterkamp, an equivalent construct in TypeScript would necessitate a distinct interface compared to a standard list. Moreover, we could design functions for transitioning between the interfaces [number, [number]]
and [number]
.
To elaborate further, consider the following TypeScript code snippet:
type NumberPair = [number, number];
const x: NumberPair = [1, 1];
const y = x[2];
Error will be triggered in TypeScript since accessing index [2]
within NumberPair
is invalid. Likewise, for lists of variable length, the element's type at an index becomes
T | undefined</code; this uncertainty arises from the possibility of index <code>i
not existing within a list. However, in a non-empty list, certainty prevails that index 0
does exist. Hence my inquiry revolves around whether TypeScript can dynamically ascertain that obtaining at least one element from a certain type is always achievable based on the type signature.