Skip to content

Conversation

@suejeong
Copy link
Collaborator

@suejeong suejeong commented Jun 16, 2025

정답 코드를 활용해 진행했습니다.

@loquemedalagana

요구사항

기본

  • Github에 위클리 미션 PR을 만들어 주세요.
  • React 및 Express를 사용해 진행합니다.
  • TypeScript를 활용해 프로젝트의 필요한 곳에 타입을 명시해 주세요.
  • any 타입의 사용은 최소화해 주세요.
  • 복잡한 객체 구조나 배열 구조를 가진 변수에 인터페이스 또는 타입 별칭을 사용하세요.
  • Union, Intersection, Generics 등 고급 타입을 적극적으로 사용해 주세요.
  • 타입 별칭 또는 유틸리티 타입을 사용해 타입 복잡성을 줄여주세요.
  • 타입스크립트 컴파일러가 에러 없이 정상적으로 작동해야 합니다.

백엔드 요구사항

  • 기존 Express.js 프로젝트를 타입스크립트 프로젝트로 마이그레이션 해주세요.
  • tsconfig.json 파일을 생성하고, 필요한 컴파일러 옵션을 설정해야 합니다. (예: outDir).
  • TypeScript 관련 명령어를 package.json에 설정해 주세요. (예: 빌드 및 개발 서버 실행 명령어).
  • ts-node와 nodemon을 사용하여 개발 환경을 구성합니다.
  • nodemon과 함께 ts-node를 사용하여 . ts 파일이 변경될 때 서버를 자동으로 재시작하도록 설정합니다.
  • Mongoose나 Prisma 등 ORM을 사용하는 경우, 모델에 대한 인터페이스 또는 타입을 정의합니다.
  • 필요한 경우, declare를 사용하여 타입을 오버라이드하거나 확장합니다.

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@suejeong suejeong requested a review from loquemedalagana June 16, 2025 09:04
getFavoriteCount() {
return this._likes.length;
}
}
Copy link
Contributor

@loquemedalagana loquemedalagana Jun 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 코드는 JavaScript 스타일에 가까우며, TypeScript 클래스의 캡슐화 및 타입 안정성을 강화하기 위해 아래와 같이 개선할 수 있습니다.


✅ 리팩토링 방향 요약

항목 현재 상태 개선 방향
필드 선언 암묵적 타입 (e.g. _id;) private _id: string; 등 명시적 타입 사용
접근 제한자 없음 private, readonly, public 등으로 캡슐화
생성자 param 직접 할당 인터페이스로 타입 보장
Getter OK 유지 가능, 혹은 readonly 속성으로 대체 가능

🔧 리팩토링 예시

import { TArticleParam } from "@/types/article";
import { TLikeParam } from "@/types/like";

export class Article {
  private readonly _id: string;
  private readonly _writerId: number;
  private readonly _title: string;
  private readonly _content: string;
  private readonly _image?: string;
  private readonly _createdAt: string;
  private readonly _updatedAt: string;
  private readonly _likes: TLikeParam[];

  constructor(param: TArticleParam) {
    this._id = param.id;
    this._writerId = param.writerId;
    this._title = param.title;
    this._content = param.content;
    this._image = param.image;
    this._createdAt = param.createdAt;
    this._updatedAt = param.updatedAt;
    this._likes = param.likes ?? [];
  }

  get id(): string {
    return this._id;
  }

  get writerId(): number {
    return this._writerId;
  }

  get title(): string {
    return this._title;
  }

  get content(): string {
    return this._content;
  }

  get image(): string | undefined {
    return this._image;
  }

  get createdAt(): string {
    return this._createdAt;
  }

  get updatedAt(): string {
    return this._updatedAt;
  }

  getFavoriteCount(): number {
    return this._likes.length;
  }

  isFavoritedBy(userId: number): boolean {
    if (!userId) return false;
    return this._likes.some((like) => like.userId === userId);
  }
}

📌 정리

  1. 접근 제한자 (private, readonly) 사용은 TypeScript의 강점 중 하나로, 외부에서 직접 필드 변경을 막을 수 있음.
  2. Getter 메서드는 그대로 유지해도 되고, ES6 Getter(get) 문법으로 자연스럽게 노출 가능.
  3. 네이밍getXxx() 대신 xxxisFavoritedBy() 등 의미 중심으로 리팩토링 가능.
  4. 타입 명시 강화: string, number, undefined 등을 명확히 명시하여 타입 안정성 확보.

/**
* 현재 시각으로부터 1시간동안 유효한 액세스 토큰을 생성합니다.
*/
static buildAccessToken(payload: any) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any 타입은 피하고 명시적인 인터페이스와 타입가드를 사용해 주세요. payload, authorizationHeaderValue, jwt.decode()의 반환값 등에 모두 명확한 타입 지정을 권장합니다.

@loquemedalagana
Copy link
Contributor

전체적으로 배운 내용 및 새로운 부분들 정리 너무 잘 해주셨어요. any사용 등 javascript 스타일이 남아있는게 아쉽지만 generic 부분 및 union, Pick 등도 한번 알아보세요!

@loquemedalagana loquemedalagana merged commit 8f8d39f into codeit-sprint-fullstack:express-황수정 Jun 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants