UNPKG

telefunc

Version:

Remote functions. Instead of API.

41 lines (40 loc) 5.02 kB
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false; type UnionToIntersection<T> = (T extends T ? (params: T) => any : never) extends (params: infer P) => any ? P : never; type UnionToTuple<T, Res extends any[] = []> = UnionToIntersection<T extends any ? () => T : never> extends () => infer ReturnType ? UnionToTuple<Exclude<T, ReturnType>, [...Res, ReturnType]> : Res; type ShieldRes<S extends string, Acc extends string[] = []> = { str: S; acc: Acc; }; type SimpleType<T, Acc extends any[] = []> = Equals<T, string> extends true ? ShieldRes<'__telefunc_t.string', Acc> : Equals<T, number> extends true ? ShieldRes<'__telefunc_t.number', Acc> : Equals<T, boolean> extends true ? ShieldRes<'__telefunc_t.boolean', Acc> : Equals<T, Date> extends true ? ShieldRes<'__telefunc_t.date', Acc> : Equals<T, any> extends true ? ShieldRes<'__telefunc_t.any', Acc> : false; type ReplaceAll<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${infer Before}${From}${infer After}` ? `${Before}${To}${ReplaceAll<After, From, To>}` : S; type Literal<T, Acc extends any[]> = T extends string ? ShieldRes<`__telefunc_t.const('${ReplaceAll<T, "'", "\\'">}')`, Acc> : T extends boolean ? ShieldRes<`__telefunc_t.const(${T})`, Acc> : T extends number ? ShieldRes<`__telefunc_t.const(${T})`, Acc> : false; type Joined<T extends any[], Acc extends any[], List = ShieldList<T>, J = JoinShieldResList<List>> = J extends string ? ShieldRes<J, Acc> : never; type ArrayLike<T extends any[], Acc extends any[] = []> = T extends [...infer U] ? Equals<U['length'], number> extends true ? T extends (infer V)[] ? Shield<V, ['array', ...Acc]> : never : ShieldList<U> extends ShieldRes<any, any>[] ? Joined<U, ['tuple', ...Acc]> : never : never; type JoinRecord<T extends Record<string, ShieldRes<any, any>>, Acc extends any[]> = ShieldRes<JoinStrings<UnionToTuple<{ [K in Extract<keyof T, string>]: `${K}: ${WrapShieldRes<T[K]>}`; }[Extract<keyof T, string>]>>, [ '{}', ...Acc ]>; type ShieldRecord<T extends Record<string, any>> = { [K in Extract<keyof T, string> as K]: Shield<T[K]>; }; type KeyValueShieldRes<T extends Record<string, any>, Acc extends any[]> = ShieldRecord<T> extends Record<any, any> ? JoinRecord<ShieldRecord<T>, Acc> : never; type KeyValueOrObjectShield<T extends Record<string, any>, Acc extends any[]> = T extends Record<infer K, infer V> ? Equals<K, string> extends true ? Shield<V, ['object', ...Acc]> : KeyValueShieldRes<T, Acc> : KeyValueShieldRes<T, Acc>; type Shield<T, Acc extends any[] = []> = SimpleType<T> extends ShieldRes<any> ? SimpleType<T, Acc> : undefined extends T ? Shield<Exclude<T, undefined>, ['optional', ...Acc]> : null extends T ? Shield<Exclude<T, null>, ['nullable', ...Acc]> : IsUnion<T> extends true ? ShieldUnion<T, Acc> : T extends any[] ? ArrayLike<T, Acc> : T extends Record<any, any> ? KeyValueOrObjectShield<T, Acc> : [Literal<T, Acc>] extends [ShieldRes<any, any>] ? Literal<T, Acc> : never; type ShieldUnion<T, Acc extends any[]> = ShieldList<UnionToTuple<T>> extends ShieldRes<any, any>[] ? Joined<UnionToTuple<T>, ['union', ...Acc]> : never; type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true; type Wrap<T extends string, Keyword> = Keyword extends 'nullable' ? `__telefunc_t.nullable(${T})` : Keyword extends 'optional' ? `__telefunc_t.optional(${T})` : Keyword extends 'tuple' ? `__telefunc_t.tuple(${T})` : Keyword extends 'array' ? `__telefunc_t.array(${T})` : Keyword extends '{}' ? `{ ${T} }` : Keyword extends 'union' ? `__telefunc_t.or(${T})` : Keyword extends 'object' ? `__telefunc_t.object(${T})` : T; type WrapShieldRes<T extends ShieldRes<any, any>> = T extends ShieldRes<infer S, infer Acc> ? Acc extends [infer Head, ...infer Tail] ? Tail extends any[] ? WrapShieldRes<ShieldRes<Wrap<S, Head>, Tail>> : never : S : never; type Sep<T> = T extends '' ? '' : ', '; type JoinShieldResList<T, Acc extends string = ''> = T extends [infer Head, ...infer Tail] ? Head extends ShieldRes<any, any> ? Tail extends ShieldRes<any, any>[] ? JoinShieldResList<Tail, `${Acc}${Sep<Acc>}${WrapShieldRes<Head>}`> : Acc : Acc : Acc; type ShieldList<T extends any[]> = Head<T> extends never ? [] : [Shield<Head<T>>, ...ShieldList<Tail<T>>]; type JoinStrings<T extends any[], Acc extends string = ''> = T extends [infer Head, ...infer Tail] ? Head extends string ? JoinStrings<Tail, `${Acc}${Sep<Acc>}${Head}`> : Acc : Acc; type ShieldStr<T, Res = Shield<T>> = Res extends ShieldRes<any, any> ? WrapShieldRes<Res> : never; export type Tail<L extends any[]> = L extends readonly [] ? [] : L extends readonly [any?, ...infer LTail] ? LTail : []; export type Head<L extends any[]> = L['length'] extends 0 ? never : L[0]; type ShieldStrMap<T extends any[]> = { [K in keyof T]-?: T[K] extends undefined ? never : ShieldStr<T[K]>; }; export type ShieldArrStr<T extends any[], M = ShieldStrMap<T>> = M extends any[] ? `[${JoinStrings<M>}]` : never; export {};