Hej! Ostatnie trzy posty w tej kategorii były odemnie i nie inaczej jest tym razem. Moim potajemnym planem jest zdominowanie tej kategorii. Dzisiaj przychodze z czymś co wymyśliłem w trakcie codereview taska do [projektu komercyjnego]. Nie będę wrzucał tutaj za dużo kodu tak, żeby mnie Kuba za NDA nie dojechał więc się ograniczę do tych fragmentów co nie ujawniają niczego.
Mianowicie chciałem użyć context jako argument funkcji i odwołać się w niej do pola które miała klasa rozszerzająca App
(ctx.app as TheApp).mssql //...
Przez to potrzebowałem własnie zrobić taką assercję, które w tym akurat projekcie są przez linter zabronione. Wymyśliłem więc, że może ten typ może przyjmować template typu jakiego aplikacja jest. Zrobiłem nawet działający proof of concetp. Najpierw dodałem taki templatedo kontextu w sealiousie
import App from "./app/app";
import { CollectionItem } from "./main";
export default class Context<T extends App = App> {
app: T;
timestamp: number;
ip: string | null;
user_id: string | null;
user_data: null | Promise<CollectionItem>;
loading_user_data: boolean;
session_id: string | null;
is_super: boolean;
original_context: Context | null;
constructor(app: App, timestamp?: number, user_id?: string | null, session_id?: string | null);
getUserData(app: App): Promise<CollectionItem | null>;
toDBEntry(): {
timestamp: number;
ip: string | null;
user_id: string | null;
session_id: string | null;
};
}
export declare class SuperContext extends Context {
is_super: boolean;
}
Następnie w samej aplikacji już dodałem to
import Mailer from "../email/mailer";
import Emittery from "emittery";
import Datastore from "../datastore/datastore";
import Metadata from "./metadata";
import { PartialConfig } from "./config";
import { ManifestData } from "./manifest";
import Logger from "./logger";
import ConfigManager from "./config-manager";
import HttpServer from "../http/http";
import Context, { SuperContext } from "../context";
import Collection from "../chip-types/collection";
import Users from "./collections/users";
import Sessions from "./collections/sessions";
export declare type AppEvents = "starting" | "started" | "stopping" | "stopped";
/** The heart of your, well app. It all starts with `new App(...)` */
declare abstract class App {
/** The current status of the app */
status: "stopped" | "running" | "starting" | "stopping";
// ...
/** A shorthand-way to create a new context: `new app.Context()`. */
Context: new () => Context<this>;
Potem jako wisienka na torcie musieliśmy powiedzieć jakiej aplikacji kontext nasz BaseContext
z koa przechowuje
declare module "koa" {
interface BaseContext {
$context: Sealious.Context<TheApp>;
$app: TheApp;
$body: Record<string, unknown>;
}
}
Po tych skomplikowanych operacjach byłem w stanie zrobić taką deklarację fukncji
async totalnieAnonimowaFunkcja(
ctx: Context<TheApp>
): Promise<(Invoice & Contractor & { Id: number[] })[]> {
return await ctx.app
.mssql //...
Nie jest to gotowe rozwiązanie wiadomo, a jedynie koncept mogłem w tym pominąć ważne rzeczy, ale sam pomysł wydał mi się ciekawy i chciałem go tu na formum zaproponować. Po tych zmianach z sukcesem odpliłem aplikację oraz przeszły wszsystkie testy, a jednocześnie pozbyłem się tych assercji.
Dajcie znać co o tym myślicie czy już oszalałem do reszty czy nie xd