This commit is contained in:
2023-08-07 18:23:37 +00:00
parent 3f7e645e40
commit b30dde442b
+72
View File
@@ -0,0 +1,72 @@
import { InvalidConversion } from "./base";
export interface Converter<Out, In extends object = Record<string, never>> {
(inCtx: In): Out;
}
type Empty = Record<string, never>;
interface Login {
userID: number;
}
interface GameLogin {
userID: number;
generalID: number;
}
interface UserLevel {
userID: number;
userLevel: number;
}
export function ParseUserLevel<Q extends Login = Login>(): Converter<Q & UserLevel, Q> {
return (inCtx: Q): Q & UserLevel => {
return {
userLevel: 123,
...inCtx,
};
}
}
export function ReqLogin<Q extends object = Empty>(): Converter<Q & Login, Q> {
return (inCtx: Q): Q & Login => {
return {
userID: 999,
...inCtx,
};
}
}
export function ReqGameLogin<Q extends Login = Login>(): Converter<Q & GameLogin, Q> {
return (inCtx: Q): Q & GameLogin => {
return {
generalID: inCtx.userID * 4,
...inCtx,
};
}
}
const x = [
ReqLogin(),
ParseUserLevel(),
] as const;
const y = [
ReqLogin,
ParseUserLevel,
ReqGameLogin,
] as const;
type Split<A> = A extends (q: infer Q) => infer R ? [Q, R] : never;
type Compose<B, A> = B extends A ? B : never;
type Compose2<B, A extends object, D, C extends object> = D & B extends A & C ? B extends C ? Converter<D, A> : never : never;
type Chain<T> =
T extends readonly [() => Converter<infer B, infer A>] ? Converter<B & A, A> :
T extends readonly [() => Converter<infer B, infer A>, () => Converter<infer D, infer C>] ? Compose2<B, A, D, C> :
T extends readonly [() => Converter<infer B, infer A>, () => Converter<infer D, infer C>, ... infer R] ? Chain<[() => Compose2<B, A, D, C>, ...R]> :
never;
type Solve<T> = T extends Converter<infer B, infer A> ? Empty extends A ? B : never : never;
type Z = Solve<Chain<typeof y>>;