본문 바로가기

javascript/nodejs

[nodejs] express-session typescript와 사용하기

 express-session 모듈을 사용할 때 데이터는 req.session.~ 형태로 추가한다. 이때 추가되는 객체는 @types/express-session을 따로 설치하더라도 인식되지 않는다. 따라서 따로 타입 정의를 해줘야 한다.

 타입 정의를 작성할 파일은 tsconfig.json 파일 내에 rootDir로 정의된 경로 내에 존재해야 타입 추론이 정상적으로 진행되는 것으로 보이며, 방법은 크게 2개로 나뉜다.

  • src/@types 폴더 내 *.d.ts 파일 내에 정의한다.
  • src/global.d.ts 파일 내에 정의한다.

 두가지 방법 중 어떤 방법을 선택했다고 가정하고, req.session의 구조를 살펴보자.

/**
 * This request's `Session` object.
 * Even though this property isn't marked as optional, it won't exist until you use the `express-session` middleware
 * [Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) can be used to add your own properties.
 *
 * @see SessionData
 */
session: session.Session & Partial<session.SessionData>;

@types/express-session 의 index.d.ts 파일 안을 살펴보면 Request.session이 Session과 SessionData를 결합한 것이며, declaration merging을 통해 프로퍼티를 추가하라는 듯한 주석을 남겨 두었다. SessionData를 찾아가면 다음과 같다,

interface SessionData {
    cookie: Cookie;
}

 SessionData는 단순히 쿠키만 담긴 인터페이스로, 이 인터페이스를 사용자의 @types 폴더 또는 global.d.ts 파일 내에서 선언하고 사용자의 데이터를 정의함으로써 사용자가 추가한 데이터가 정상적으로 타입스크립트에 의해 인식된다.

import 'express-session';

declare module 'express-session' {
  interface SessionData {
    views: number;
  }
}

위 코드의 SessionData 내에 사용자가 정의한 자료를 추가하면 정의 상에 반영된다.

chatgpt에 따르면 import의 경우 express-session의 타입 정보를 가져오기 위한 목적으로 사용된다고 한다. 예전에 실행했을 때는 굳이 import가 없더라도 session 데이터 정보를 가져올 수 있었는데, 다른 프로젝트에서 실행해보니 어딘가 설정이 다르기 때문인지 제대로 동작하지 않았다. 이때 import 문을 추가하니 declare merging이 정상적으로 동작했다.

타입 선언 파일은 루트의 @types 폴더 내에 저장했다. 이 경우 프로젝트 폴더 내 어디에 선언하든 정확하게 merging을 수행하여 내가 원하는 데이터 타입을 얻을 수 있었다. 이전 상황과 무엇이 다른지는 잘 모르겠으나, 공통적으로 동작했던 src/global.d.ts 파일 내 정의가 가장 편한 것 같다.

 처음에는 Express 객체의 Request 객체에 session 객체를 정의하고 이 안에 user 을 추가해서 확장되기를 기대했는데, 이렇게 하면 오히려 session 객체가 @types/exress-session에 정의된 Request.session 타입을 가려서 제대로 동작하지 않았다. 타입 선언에 대해 좀 더 깊게 공부해야 할 것 같다.

'javascript > nodejs' 카테고리의 다른 글

[nodejs] libuv  (0) 2023.08.16
[nodejs] esbuild 전체 폴더 감시하기  (0) 2023.05.30
[nodejs] prisma ORM 라이브러리  (0) 2023.02.22
[nodejs] mysql2 라이브러리  (0) 2023.02.14
[오늘의 삽질] web-tree-sitter 과 emscripten  (0) 2022.05.10