export type ArrayIndexReturnValue < A extends ArrayLike < unknown > , I extends PropertyKey > = I extends number ? A [ number ] extends A [ I ] ? number extends A [ "length" ] ? A [ I ] | undefined : undefined : number extends A [ "length" ] ? A [ I ] | undefined : A [ I ] : undefined ; export type GetReturnType < A extends Record < PropertyKey , unknown > | ArrayLike < unknown > , I extends A extends ArrayLike < unknown > ? ArrayIndex < A > : keyof A > = A extends ArrayLike < unknown > ? ArrayIndexReturnValue < A , I > : A extends { readonly [ i in I ] : unknown ; } ? A [ I ] : A [ I ] | undefined ; type ArrayIndex < A extends ArrayLike < unknown > > = number extends A [ "length" ] ? number : 0 extends A [ "length" ] ? never : 1 extends A [ "length" ] ? 0 : 2 extends A [ "length" ] ? 0 | 1 : 3 extends A [ "length" ] ? 0 | 1 | 2 : 4 extends A [ "length" ] ? 0 | 1 | 2 | 3 : 5 extends A [ "length" ] ? 0 | 1 | 2 | 3 | 4 : 6 extends A [ "length" ] ? 0 | 1 | 2 | 3 | 4 | 5 : 7 extends A [ "length" ] ? 0 | 1 | 2 | 3 | 4 | 5 | 6 : 8 extends A [ "length" ] ? 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 : 9 extends A [ "length" ] ? 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 : number ; see https export const get = < A extends Record < PropertyKey , unknown > | ArrayLike < unknown > , I extends A extends ArrayLike < unknown > ? ArrayIndex < A > : keyof A > ( a , i ) : GetReturnType < A , I > => a [ i ] as GetReturnType < A , I > ; /**
 * An escape hatch for when you can't make the types line up in `get` and are willing
 * to accept undefined always being included in the return type.
 */ export const getOrUndefined = < A , I extends keyof A > ( a , i ) : A [ I ] | undefined => a [ i ] ;