Is it possible to get a correctly typed sub-tuple?

229 Views Asked by At

With variadic tuple types Typescript allows me to define generic Types that isolate Parts from a tuple type.
For the sake of simplicity in this question, let us just talk about splitting the first length-1 elements and the last:

type Head<T extends any[]> = T extends [ ...infer Head, any ] ? Head : any[];

Now assume I have some typed tuple instance and want to get both

  • the first length - 1 elements and
  • the last element

const args: [...T, D] // assume I have that in a context where T and D exist
const last: D = args[-1] // this works just fine
const head: T = args.slice(0, -1) // this does not - I have to cast as unknown as T

Is there a way to get the head properly typed without having to cast?

1

There are 1 best solutions below

0
Filly On

You could declare some helper functions for your problem:

type Tuple = ["a", "b"]

function accessTypesafeIndex<T extends any[], K extends keyof T>(arr: T, key: K): T[K] {
    return arr[key]
}
const t: Tuple = ["a", "b"]

const x = accessTypesafeIndex(t, 1) // "b"
const z = accessTypesafeIndex(t, 0) // "a"
const y = accessTypesafeIndex(t, 2) // undefined

function last<T extends any[]>(arr: T): T extends [...any[], infer Rest] ? Rest : undefined {
    return arr[arr.length - 1]
}
const l = last(t)//"b"
function head<T extends any[]>(arr: T): T extends [infer Head, ...any[]] ? Head : undefined {
    return arr[arr.length - 1]
}
const h = head(t)//"a"

playground