꼬이네..

This commit is contained in:
2023-08-08 15:41:08 +00:00
parent 96b18ad5ff
commit deb989e45b
4 changed files with 172 additions and 153 deletions
+12 -122
View File
@@ -1,67 +1,28 @@
import type { Request, Response } from "express";
import type { InvalidResponse } from "../../apiStructure/defs";
type MayBePromise<T> = T | Promise<T>;
export type InvalidProc = {
export type Empty = Record<string, never>;
export type InvalidProc = InvalidResponse & {
invalidProcSymbol: unknown;
reason?: string;
alreadyProcessed?: boolean;
}
};
export interface ProcDecorator<Out, In extends object = Record<string, never>> {
(inCtx: In, req: Request, res: Response): MayBePromise<Out | InvalidProc>;
}
export type Empty = Record<string, never>;
type Login = {
userID: number;
}
type GameLogin = {
userID: number;
generalID: number;
}
type UserLevel = {
userID: number;
userLevel: number;
}
export function ParseUserLevel<Q extends Login = Login>(): ProcDecorator<Q & UserLevel, Q> {
return (inCtx) => {
return {
userLevel: 123,
...inCtx,
};
}
}
export function ReqLogin<Q extends object = Empty>(): [ProcDecorator<Q & Login, Q>, ProcDecorator<Login & object, Login & object>] {
return [
(inCtx) => {
return {
userID: 999,
...inCtx,
};
},
(inCtx) => {
//무언가
return inCtx;
}
]
}
export function ReqGameLogin<Q extends Login = Login>(): ProcDecorator<Q & GameLogin, Q> {
return (inCtx) => {
return {
generalID: inCtx.userID * 4,
...inCtx,
};
}
(inCtx: In, req: Request, res: Response, isValidRoute: boolean): MayBePromise<Out | InvalidProc>;
}
export type ProcDecoratorGenerator<B extends object, A extends object> = ProcDecorator<B & A, A>;
export type ProcDecoratorPrePostGenerator<B extends object, A extends object> = [ProcDecorator<B & A, A>, ProcDecorator<B & object, B & object>];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ProcDecoratorChain = undefined | readonly ((() => ProcDecorator<any, any>) | (() => [ProcDecorator<any, any>, ProcDecorator<any, any>]))[];
export type ResolveChain<T> = T extends undefined ? Empty : T extends ProcDecoratorChain ? Resolve<PackChain<T>> : never;
type Compose2<B extends object, A extends object, D, C> = D & B extends A & C ? B extends C ? ProcDecorator<D & B, A> : never : never;
type PD1<B extends object, A extends object> = () => ProcDecorator<B, A>;
@@ -79,74 +40,3 @@ type PackChain<T> =
never;
type Resolve<T> = T extends ProcDecorator<infer B, infer A> ? Empty extends A ? B : never : never;
export type ResolveChain<T extends ProcDecoratorChain> = Resolve<PackChain<T>>;
const q1 = [
ReqLogin,
ParseUserLevel,
ReqGameLogin,
] as const;
const q2 = [
ReqLogin,
ParseUserLevel,
] as const;
type R1 = Resolve<PackChain<typeof q1>>;
type R2 = Resolve<PackChain<typeof q2>>;
const r1: R1 = undefined as unknown as R1;
const r2: R2 = undefined as unknown as R2;
r1.userLevel;
r2.userID;
async function test(req: Request, res: Response) {
const a0 = await ReqLogin()[0]({}, req, res);
if ('invalidProcSymbol' in a0) {
return false;
}
const a1 = await ParseUserLevel()(a0, req, res);
if ('invalidProcSymbol' in a1) {
return false;
}
const a2 = await ReqGameLogin()(a1, req, res);
if ('invalidProcSymbol' in a2) {
return false;
}
const b0 = await ReqLogin()[1](a2, req, res);
return true;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ProcDecoratorChain = readonly ((() => ProcDecorator<any, any>) | (() => [ProcDecorator<any, any>, ProcDecorator<any, any>]))[];
function unpack2<A extends ProcDecorator<any, any>, B>(v: A | [A, B]): A {
if (Array.isArray(v)) {
return v[0];
}
return v;
}
function test2<T extends ProcDecoratorChain>(req: Request, res: Response, chain: T): Resolve<PackChain<T>> | false {
const tmp = chain[0]();
const actors = chain.map((v) => unpack2(v()));
let result = {};
for (const actor of actors) {
result = actor(result, req, res);
if ('isInvalid' in result) {
return false;
}
}
return result as Resolve<PackChain<T>>;
}
const finalResult1 = test2({} as Request, {} as Response, q1);
if (finalResult1 !== false) {
finalResult1.userLevel;
}