// ============ An implementation of first() ============ /** * Get the type of the ith element of a tuple. * Kind: Vector -> number -> * */ type ElementOf = Arr[Index] // An example - this returns the type of the second element of the tuple // In this case, literal values are types (kinda), so this resolves to the literal type 'hello' // That is, it is satisfiable by the subset of strings {hello} // In an editor like VSCode, hover over the name of the type to see what it resolved to type ExampleElementOf = ElementOf<[true, 'hello', 3.14], 1> // This succeeds because the value 'hello' is assignable to the type 'hello' const exampleElementGood: ExampleElementOf = 'hello' // This fails because the value 'fubar' is not assignable to the type 'hello' // const exampleElementBad: ExampleElementOf = 'fubar' /** * Accepts non-empty tuples. * Does this by coercing the inferred tuple Arr to the intersection type Arr with an interface * that MUST have an index 0 which has the type of the first element of Arr. * Kind: Vector -> * */ type NonEmpty = Arr & { 0: ElementOf } /** * Gets the first element of a non-empty tuple. * * Accepts a parameter `arr` of type `NonEmpty` where `Arr` is the inferred * type of the tuple. * * @param arr */ function first(arr: NonEmpty): ElementOf { return arr[0] } const firstNumber = first([3.14]) // => type: number const firstString = first(['hello', 3.14]) // => type: string // const firstEmpty = first([]) // => type: never