1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elysiaでコンテキストの型を保ってderiveしようとしたときに型が循環参照した時の対処法

Posted at

コンテキストの型を保ってderiveしようとして循環参照したので、その問題とその対処法を書きます。

コード

これは問題が起きたソースコードを切り取ったものです

app.ts
import jwt from "@elysiajs/jwt";
import swagger from "@elysiajs/swagger";
import Elysia, { InferContext } from "elysia";
import { key } from "./secret";
import cors from "@elysiajs/cors";
import { deriveSigninedUser } from "./user";

const version = "0.0.0";

export type ElysiaContext = InferContext<ReturnType<typeof createElysiaApp>>;

export const createElysiaApp = (name: string) => new Elysia()
  .use(swagger({ documentation: { info: { title: name + " document", version } } }))
  .use(jwt({ name: "jwt", secret: key.privateKey }))
  .use(cors({
    origin: "http://localhost:4517",
    allowedHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests', 'Content-type', 'X-Token', 'X-Csrftoken'],
    methods: ['POST', 'PUT', 'GET', 'OPTIONS'],
    exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
    maxAge: 600,
    credentials: true,
  }))
  .derive(deriveSigninedUser);

user.ts
import { ElysiaContext } from "./app";
// なんちゃら~...

export const deriveSigninedUser = async ({ cookie, headers, jwt }: ElysiaContext): Promise<{
  user?: typeof DBUserSchema.static | null
}> => {
  // なんちゃら~...

  if(typeof payload.aud !== "string") return {}; 

  return { user: getUser(payload.aud) };
}

問題

そうしてapp.tsに移動して、deriveを付け足すと...

'createElysiaApp' は、戻り値の型の注釈がなく、いずれかの return 式で直接的にまたは間接的に参照されているため、戻り値の型は暗黙的に 'any' になります。

どういうことだあ...?

そして上(ElysiaContext)に赤線があり、それを見ると...

型のエイリアス 'ElysiaContext' が自身を循環参照しています。

循環参照だった\(^o^)/

循環構造

ファイル跨いでいてわかりづらかったけど普通に循環してる...

対処法

deriveをするコードをこのcreateElysiaAppから分離しましょう。

app.ts(例)
import jwt from "@elysiajs/jwt";
import swagger from "@elysiajs/swagger";
import Elysia, { InferContext } from "elysia";
import { key } from "./secret";
import cors from "@elysiajs/cors";
import { deriveSigninedUser } from "./user";

const version = "0.0.0";

export type ElysiaContext = InferContext<ReturnType<typeof createElysiaApp>>;

export const createElysiaApp = (name: string) => new Elysia()
  .use(swagger({ documentation: { info: { title: name + " document", version } } }))
  .use(jwt({ name: "jwt", secret: key.privateKey }))
  .use(cors({
    origin: "http://localhost:4517",
    allowedHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests', 'Content-type', 'X-Token', 'X-Csrftoken'],
    methods: ['POST', 'PUT', 'GET', 'OPTIONS'],
    exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
    maxAge: 600,
    credentials: true,
  }));

export const createElysiaAppWithDerive = (name: string) =>
  createElysiaApp(name).derive(deriveSigninedUser);

みんなもこれが起きたら試してみてね!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?