[Turborepo] 공용타입 워크스페이스 설정

아홉번째태양·2023년 7월 22일
1

프로젝트 트리

📦 
├─ apps
│  ├─ api
│  └─ web
├─ packages
│  ├─ tsconfig
│  ├─ eslint
│  └─ types
└─ turbo.json

©generated by Project Tree Generator

turborepo에서 위와 같은 구조의 풀스택 프로젝트를 만들 때, types에 공용 타입들을 정의하고 각 워크스페이스에서 export 없이 글로벌로 타입을 사용해서 쓰려한다.

types 워크스페이스 설정

types 디렉토리를 만들고, 초기화를 하고, 필요한 패키지를 설치한다.

$ mkdir packages/types && cd packages/types
$ pnpm init

// back to root
$ cd ../..
$ pnpm add --save-dev typescript --filter types

그리고 tsconfig를 base.json에서 가져온다.

$ pnpm add --save-dev tsconfig@workspace --filter types

// packages/types/tsconfig.json
{
  "extends": "tsconfig/base.json",
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "dist",
  },
  "include": [
    "src/**/*"
  ],
}

package.json

maintypes 경로를 빌드한 이후로 잡아줘야한다.

{
  "name": "types",
  "version": "1.0.0",
  "description": "",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "scripts": {
    "build": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "tsconfig": "workspace:*",
    "typescript": "^5.1.6"
  }
}

types 작성

필요한 타입들을 작성해 넣는다.

  • 예시.
// packages/types/src/user.ts
declare global {
  /**
   * @type uuid
   */
  type UserId = string;
  type UserName = string;
  type UserEmail = string;

  type User = {
    _id: ObjectId;
    userId: UserId;
    name: UserName;
    email : UserEmail;
    photo: string;
    googleKey: GoogleKey
    projects: ObjectId[];
    createdAt: Date | string;
    updatedAt: Date | string;
  }

  type UserType = typeof UserType[keyof typeof UserType];
  type UserPayload = {
    type: UserType;
    userId: string;
    name: string;
  }

  type Profile = UserPayload & {
    email: string;
    photo: string;
  }
}

export const UserType = {
  GUEST: 'Guest',
  USER: 'User',
  ADMIN: 'Admin',
} as const;

types 빌드

types만 빌드를 한다.

$ pnpm build --filter types

다른 워크스페이스에 적용하기

의존성 설치

공용타입 워크스페이스를 사용하려는 워크스페이스에 해당 패키지를 설치한다.

$ pnpm add --save-dev types@workspace --filter api

설치가되고나면 이제 packages/types의 변경사항이랑 설치한 워크스페이스에서 apps/api/node_modules/types가 서로 연동되는 것을 확인할 수 있다.

코드에서 사용

이제 types에서 글로벌로 정의한 타입들을 설치한 워크스페이스에서도 별도의 import 없이 타입 사용이 가능하다.

// apps/api/src/users/auth.guard.ts

const payload: UserPayload = this.jwt.verify(token);

객체 import

타입 이외에 객체나 함수 등을 임포트할 때는 그대로 types로부터 가져오면 된다.

import { UserType } from 'types';
const type = UserType.GUEST;

0개의 댓글