type Take<N extends number, Arr extends any[], _Result extends any[] = [], _AbsN = `${N}` extends `-${infer A extends number}` ? A : N> =
_Result[`length`] extends _AbsN ? _Result :
// Arr extends [] ? _Result : //optional
N extends _AbsN ?
Arr extends [infer F, ...infer R] ? Take<N, R, [..._Result, F]> : _Result : //positive
Arr extends [...infer R, infer L] ? Take<N, R, [L, ..._Result]> : _Result; //nagative
Solution by E-uler #34715
type Take<N extends number, Arr extends unknown[], Result extends unknown[] = []> =
Absolute<N> extends 0
? []
: Or<[
Absolute<N> extends Result["length"] ? true : false,
Arr extends [] ? true : false
]> extends true
? Result
: N extends Absolute<N>
? Arr extends [infer First, ...infer Rest]
? Take<N, Rest, [...Result, First]>
: never
: Arr extends [...infer Rest, infer Last]
? Take<N, Rest, [Last, ...Result]>
: never;
type Absolute<N extends number> = `${N}` extends `-${infer AbsoluteN extends number}` ? AbsoluteN : N;
type NonEmptyArray<T> = [T, ...T[]];
type Or<T extends NonEmptyArray<boolean>> = T extends [infer First, ...infer Rest]
? true extends First
? true
: Rest extends NonEmptyArray<boolean>
? Or<Rest>
: false
: never;
Solution by shobande-femi #34605
// reverse order of T
// eg.
// Reverse<[1, 2, 3]> -> [3, 2, 1]
// Reverse<[]> -> []
type Reverse<T extends unknown[]> = T extends [infer First, ...infer Rest] ? [...Reverse<Rest>, First] : [];
type Take<
N extends number,
Arr extends unknown[],
Result extends unknown[] = []
> = `${N}` extends `-${infer A extends number}`
? Reverse<Take<A, Reverse<Arr>>>
: Result["length"] extends N
? Result
: Arr extends [infer First, ...infer Rest extends unknown[]]
? Take<N, Rest, [...Result, First]>
: Result;
Solution by yukicountry #34436
type Take<N extends number, Arr extends unknown[]>
= `${N}` extends `-${infer I extends number}` // Check for negative here once
? TupleTrim<[any], [], `${I}`, Arr>
: TupleTrim<[], [any], `${N}`, Arr>
type TupleTrim<Head extends any[], Tail extends any[], Key extends string, Arr extends unknown[]>
= Key extends keyof Arr
? Arr extends [...Head, ...infer Rest, ...Tail] ? TupleTrim<Head, Tail, Key, Rest> : never
: Arr // i.e. '2' extends ['0', '1'] or '2' extends ['0']
Solution by teamchong #34407
type Take<N extends number, A> = `${N}` extends `-${infer M extends number}`
? Slice<M, A, 1>
: Slice<N, A, 0>;
type Slice<N, A, L, R extends unknown[] = []> = N extends R['length']
? R
: A extends (L extends 1 ? [...infer T, infer V] : [infer V, ...infer T])
? Slice<N, T, L, L extends 1 ? [V, ...R] : [...R, V]>
: R;
Solution by alexandroppolus #34383
type MuseOne<T extends number | string, K extends unknown[] = []> = `${[...K, '']['length'] extends number
? [...K, '']['length']
: ''}` extends `${T}`
? K['length']
: MuseOne<T, [...K, '']>;
type Abs<T extends number> = `${T}` extends `-${infer K}` ? K : T;
type TakeFromFirst<T extends number, K extends unknown[]> = T extends 0
? []
: K extends [infer L, ...infer R]
? [L, ...TakeFromFirst<MuseOne<T>, R>]
: [];
type TakeFromLast<T extends number | string, K extends unknown[]> = T extends 0
? []
: K extends [...infer L, infer R]
? [...TakeFromLast<MuseOne<T>, L>, R]
: [];
type Take<T extends number, K extends unknown[]> = `${T}` extends `-${number}`
? TakeFromLast<Abs<T>, K>
: TakeFromFirst<T, K>;
Solution by chhu1 #34354
type Take<N extends number, Arr extends unknown[]> = `${N}` extends `-${infer P extends number}`
? Reverse<_Take<P, Reverse<Arr>>>
: _Take<N, Arr>
type _Take<N extends number, Arr extends unknown[], R extends unknown[] = []> = R['length'] extends N
? R
: Arr extends [infer Head, ...infer Rest]
? _Take<N, Rest, [...R, Head]>
: R
type Reverse<T extends unknown[]> = T extends [infer Head, ...infer Rest, infer Last]
? [Last, ...Reverse<Rest>, Head]
: T
Solution by Sun79 #34351