Skip to content

Instantly share code, notes, and snippets.

@rhom6us
Last active July 15, 2023 19:54
Show Gist options
  • Save rhom6us/c8fe48e31cf7418cb5577d8ce3b0d09f to your computer and use it in GitHub Desktop.
Save rhom6us/c8fe48e31cf7418cb5577d8ce3b0d09f to your computer and use it in GitHub Desktop.
pointless tuple
type Dec<Length extends number, Acc extends never[] = []> =
[never, ...Acc]['length'] extends Length ? Acc['length'] :
Dec<Length, [never, ...Acc]>;
type MakeRange<TMin extends number, TMax extends number, Acc extends number = never> =
TMax extends TMin ? TMax | Acc
: MakeRange<TMin, Dec<TMax>, TMax | Acc>;
type TupleBaseType = readonly any[] & { length: MakeRange<1,10> }
/**
* generate this code with:
* =======================
* typescript
* ----------
* (function asdaf(count:number, vacantType: string){
* const range = (length:number) => Array.from(new Array(length).keys());
* const result = `export type Tuple<${range(count).map(i => `T${i} = ${vacantType}`).join(', ')}> = \n ${range(count).slice(1, -1).map(i => `T${i} extends ${vacantType} ? readonly [${range(i).map(j => `T${j}`).join(', ')}] :`).join('\n ')}\n readonly [${range(count).map(i => `T${i}`).join(', ')}];`;
* console.log(result);
* })(20, 'void');
*
* javascript
* ----------
* (function(count,vacantType){let range=length=>Array.from(Array(length).keys()),result=`export type Tuple<${range(count).map(i=>`T${i} = ${vacantType}`).join(", ")}> =\n ${range(count).slice(1,-1).map(i=>`T${i} extends ${vacantType} ? readonly [${range(i).map(j=>"T"+j).join(", ")}] :`).join("\n ")}\n readonly [${range(count).map(i=>"T"+i).join(", ")}];`;console.log(result)})(10,"void");
*
*/
export type Tuple<T0 = void, T1 = void, T2 = void, T3 = void, T4 = void, T5 = void, T6 = void, T7 = void, T8 = void, T9 = void,> =
T1 extends void ? readonly [T0] :
T2 extends void ? readonly [T0, T1] :
T3 extends void ? readonly [T0, T1, T2] :
T4 extends void ? readonly [T0, T1, T2, T3] :
T5 extends void ? readonly [T0, T1, T2, T3, T4] :
T6 extends void ? readonly [T0, T1, T2, T3, T4, T5] :
T7 extends void ? readonly [T0, T1, T2, T3, T4, T5, T6] :
T8 extends void ? readonly [T0, T1, T2, T3, T4, T5, T6, T7] :
T9 extends void ? readonly [T0, T1, T2, T3, T4, T5, T6, T7, T8] :
readonly [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9];
// /**
// * generate this code with:
// *
// * (function(){
// * const range = (length:number) => Array.from(new Array(length).keys());
// * return range(10).map(i => `T extends [${range(i).map(j => `infer T${j+1}`).join(', ')}] ? Tuple<${range(i).map(j => `T${j+1}`).join(', ')}> :`).join('\n');
// * }());
// *
// */
// export type InferTuple<T extends TupleBaseType> =
// T extends [infer T0] ? Tuple<T0> :
// T extends [infer T0, infer T1] ? Tuple<T0, T1> :
// T extends [infer T0, infer T1, infer T2] ? Tuple<T0, T1, T2> :
// T extends [infer T0, infer T1, infer T2, infer T3] ? Tuple<T0, T1, T2, T3> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4] ? Tuple<T0, T1, T2, T3, T4> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4, infer T5] ? Tuple<T0, T1, T2, T3, T4, T5> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4, infer T5, infer T6] ? Tuple<T0, T1, T2, T3, T4, T5, T6> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4, infer T5, infer T6, infer T7] ? Tuple<T0, T1, T2, T3, T4, T5, T6, T7> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4, infer T5, infer T6, infer T7, infer T8] ? Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> :
// T extends [infer T0, infer T1, infer T2, infer T3, infer T4, infer T5, infer T6, infer T7, infer T8, infer T9] ? Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> :
// never;
/**
* generate this code with:
* =======================
* typescript
* ----------
* (function (count:number) {
* const range = (length: number) => Array.from(new Array(length).keys());
* const result = `
* export type InferTuple<T extends TupleBaseType> =
* ${range(count+1).slice(1).map(i => `T['length'] extends ${i} ? Tuple<${range(i).map(j => `T[${j}]`).join(', ')}> :`).join('\n ')}
* never;
* `;
* console.log(result);
* }(10));
*
* javascript
* ----------
* (function(e){let n=e=>Array.from(Array(e).keys()),l=`export type InferTuple<T extends TupleBaseType> = \n ${n(e+1).slice(1).map(e=>`T['length'] extends ${e} ? Tuple<${n(e).map(e=>`T[${e}]`).join(", ")}> :`).join("\n ")}\n never;`;console.log(l)})(10);
*
*/
export type InferTuple<T extends TupleBaseType> =
T['length'] extends 1 ? Tuple<T[0]> :
T['length'] extends 2 ? Tuple<T[0], T[1]> :
T['length'] extends 3 ? Tuple<T[0], T[1], T[2]> :
T['length'] extends 4 ? Tuple<T[0], T[1], T[2], T[3]> :
T['length'] extends 5 ? Tuple<T[0], T[1], T[2], T[3], T[4]> :
T['length'] extends 6 ? Tuple<T[0], T[1], T[2], T[3], T[4], T[5]> :
T['length'] extends 7 ? Tuple<T[0], T[1], T[2], T[3], T[4], T[5], T[6]> :
T['length'] extends 8 ? Tuple<T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7]> :
T['length'] extends 9 ? Tuple<T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]> :
T['length'] extends 10 ? Tuple<T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]> :
never;
// export function tuple<const T extends TupleBaseType>(...items: T) {
// if (items.length > 9) {
// throw new TypeError(
// "tuple util function only supports tuple length of up to 9"
// );
// }
// return items as unknown as InferTuple<T>;
// };
export function tuple<const T extends readonly any[]>(...items: T){
return items;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment