diff --git a/server/api/decorator/test2.ts b/server/api/decorator/test2.ts index 7d6f2b5..0c91d09 100644 --- a/server/api/decorator/test2.ts +++ b/server/api/decorator/test2.ts @@ -1,25 +1,25 @@ import { InvalidConversion } from "./base"; export interface Converter> { - (inCtx: In): Out; + (inCtx: In, req: Request, res: Response): Out | InvalidConversion; } type Empty = Record; -interface Login { +type Login = { userID: number; } -interface GameLogin { +type GameLogin = { userID: number; generalID: number; } -interface UserLevel { +type UserLevel = { userID: number; userLevel: number; } export function ParseUserLevel(): Converter { - return (inCtx: Q): Q & UserLevel => { + return (inCtx) => { return { userLevel: 123, ...inCtx, @@ -28,7 +28,7 @@ export function ParseUserLevel(): Converter(): Converter { - return (inCtx: Q): Q & Login => { + return (inCtx) => { return { userID: 999, ...inCtx, @@ -37,7 +37,7 @@ export function ReqLogin(): Converter { } export function ReqGameLogin(): Converter { - return (inCtx: Q): Q & GameLogin => { + return (inCtx) => { return { generalID: inCtx.userID * 4, ...inCtx, @@ -45,28 +45,70 @@ export function ReqGameLogin(): Converter = A extends (q: infer Q) => infer R ? [Q, R] : never; - -type Compose = B extends A ? B : never; -type Compose2 = D & B extends A & C ? B extends C ? Converter : never : never; -type Chain = - T extends readonly [() => Converter] ? Converter : +type Compose2 = D & B extends A & C ? B extends C ? Converter : never : never; +export type Chain = + T extends readonly [() => Converter] ? Converter : T extends readonly [() => Converter, () => Converter] ? Compose2 : T extends readonly [() => Converter, () => Converter, ... infer R] ? Chain<[() => Compose2, ...R]> : never; -type Solve = T extends Converter ? Empty extends A ? B : never : never; +export type Solve = T extends Converter ? Empty extends A ? B : never : never; -type Z = Solve>; + +const q1 = [ + ReqLogin, + ParseUserLevel, + ReqGameLogin, +] as const; + +const q2 = [ + ReqLogin, +] as const; + +type R1 = Solve>; +type R2 = Solve>; +const r1: R1 = undefined as unknown as R1; +const r2: R2 = undefined as unknown as R2; +r1.userLevel; +r2.userID; + + +function test(req: Request, res: Response){ + const a0 = ReqLogin()({}, req, res); + if('isInvalid' in a0){ + return false; + } + const a1 = ParseUserLevel()(a0, req, res); + if('isInvalid' in a1){ + return false; + } + const a2 = ReqGameLogin()(a1, req, res); + if('isInvalid' in a2){ + return false; + } + return true; +} + + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type Converters = readonly (() => Converter)[]; + +function test2(req: Request, res: Response, chain: T): Solve> | false{ + + const actors = chain.map((v) => v()); + + let result = {}; + for(const actor of actors){ + result = actor(result, req, res); + if('isInvalid' in result){ + return false; + } + } + return result as Solve>; +} + +const finalResult1 = test2({} as Request, {} as Response, q1); +if(finalResult1 !== false){ + finalResult1.userLevel; +} \ No newline at end of file