import type { TypeContructorASTCompiler, ChainASTCompiler, FunctionASTCompiler, TypeASTCompiler } from './ast/types'; import type { TypeConstructorMapCompiler, TypeList, TypeNameList } from './types'; import { ZipWithVariance } from '../kinds/variance'; import { StringToTuple, Range, Flatten, Drop } from '../utils/tuples'; import { Sub } from '../utils/numbers'; import { Kind, $ } from '../kinds/index.js'; import { GenericFn } from '../utils/functions'; import { ParseAST } from './ast/type-parser'; type NextAlphaMap = { A: 'B'; B: 'C'; C: 'D'; D: 'E'; E: 'F'; F: 'G'; G: 'H'; H: 'I'; I: 'J'; J: 'K'; K: 'L'; L: 'M'; M: 'N'; N: 'O'; O: 'P'; P: 'Q'; Q: 'R'; R: 'S'; S: 'T'; T: 'U'; U: 'V'; V: 'W'; W: 'X'; X: 'Y'; Y: 'Z'; Z: 'A'; }; export type GetNextAlpha = alpha extends keyof NextAlphaMap ? NextAlphaMap[alpha] : never; type GetFromList = typeNameList extends [ ...infer Rest extends TypeNameList, infer Last ] ? Last extends key ? typeList extends TypeList ? typeList[Rest['length']] : never : GetFromList : never; type MapSpreadParams = { [K in keyof Spreads]: GetFromList; }; export type BuildSpreadParams = ast['name'] extends keyof typeconstructorMap ? Sub extends infer spreadLength extends number ? MapSpread, spread> : [] : []; export type GetSpreadParams = MapSpreadParams, typeNameList, typeList>; export type MergeSpreadParams, $spreadB = GetSpreadParams> = ZipWithVariance<$spreadA, $spreadB, Drop>; type MapSpread = { [K in keyof T]: `${Spread}${T[K]}`; }; export type BuildGenericSpreadKeys = ast['name'] extends keyof typeconstructorMap ? ast['spread'] extends infer spread extends string ? StringToTuple['length'] extends 1 ? `${spread}0` extends typeNameList[number] ? [] : Sub extends infer spreadLength extends number ? MapSpread, spread> : [] : [] : [] : []; type MapGetGenericKeys = { [K in keyof T]: GetGenericKeys; }; type GetGenericKeys = ast extends TypeContructorASTCompiler ? [ ...Flatten>, ...BuildGenericSpreadKeys ] : ast extends ChainASTCompiler ? Flatten> : ast extends FunctionASTCompiler ? Flatten> : ast extends TypeASTCompiler ? ast['name'] extends typeNameList[number] ? [] : [ast['name']] : []; export type BuildSpreadKeys = ast['name'] extends keyof typeconstructorMap ? ast['spread'] extends infer spread extends string ? StringToTuple['length'] extends 1 ? Sub extends infer spreadLength extends number ? MapSpread, spread> : [] : [] : [] : []; type MapKeys = { [K in keyof T]: GetKeys; }; export type GetKeys = ast extends TypeContructorASTCompiler ? [...Flatten>, ...BuildSpreadKeys] : ast extends ChainASTCompiler ? Flatten> : ast extends FunctionASTCompiler ? type extends 'both' ? Flatten> : type extends 'args' ? Flatten> : GetKeys : ast extends TypeASTCompiler ? [ast['name']] : []; type Unique = T extends [infer Head, ...infer Tail] ? Head extends $map ? Unique : Unique : $acc; export type BuildGenericKeys = Unique>; export type BuildKeys = Unique>; type MapTypeskell = { [K in keyof params]: ParseTypeskell; }; export type BuildTypeContructor = ast extends TypeContructorASTCompiler ? MapTypeskell extends infer params extends TypeNameList ? ast['name'] extends keyof typeconstructorMap ? ast['spread'] extends string ? StringToTuple extends [infer spreadA extends string, infer spreadB extends string] ? $ ]> : GetSpreadParams extends infer SpreadParams extends TypeNameList ? $ : never : $ : never : never : never; type Filter = Keys extends [infer H, ...infer R extends TypeNameList] ? H extends typeNameList[number] ? Filter]> : Filter : [$accKeys, $accTypes]; type MapKeysToFn, $filteredArgKeysAndTypes extends [TypeNameList, TypeList] = Filter<$argKeys, typeNameList, typeList>> = GenericFn, BuildTypeskellResult>, alpha>; type ParseTypeskell = ast extends TypeContructorASTCompiler ? BuildTypeContructor : ast extends TypeASTCompiler ? GetFromList : ast extends FunctionASTCompiler | ChainASTCompiler ? BuildGenericKeys extends infer generickeys extends TypeNameList ? MapKeysToFn : never : never; interface BuildTypeskellParams extends Kind { return: this['rawArgs'] extends TypeList ? typeList extends TypeList ? MapTypeskell : never : never; } interface BuildTypeskellResult extends Kind { return: this['rawArgs'] extends TypeList ? typeList extends TypeList ? ParseTypeskell : never : never; } export type TypeSkell = ParseTypeskell, typeconstructorMap, [ 'boolean', 'number', 'string', ...typeNameList ], [ boolean, number, string, ...typeList ]>; export {};