타입스크립트 꽝꽝

[ TypeScript ] TypeORM - Cannot read properties of undefined (reading 'column') 에러 해결하기

bimppap 2022. 2. 18. 18:43

 

nest.js 웹 프레임워크를 활용해 프로젝트를 만들고 있었는데 어느 정도 도메인을 짜고 yarn start를 누르니 해당 에러가 떴다.

 

[Nest] 24529 - 02/18/2022, 6:08:29 PM ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
TypeError: Cannot read properties of undefined (reading 'id') at new Menu... (중략)
at EntityMetadata.create (...link...)
at EntityMetadataValidator.validate (...link...)

 

첫번째 시도

찾아보니 Controller, Service 단에서 리턴 타입을 명시하지 않으면 해결된다길래 아래처럼 시도했으나 여전했다.

@Delete(':menuId')
  async deleteMenu(@Param('menuId') id: number, @Res() res): Promise<any> {
    await this.menuService.delete(id);
    return res.status(204);
  }

 

두번째 시도

설마하니 생성자나 필드 변수에 타입이 명시되어 있지 않나 확인해봤지만 전부 명시되어 있었다.

@Entity({ name: 'menu', synchronize: true })
export class Menu {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;
  
  constructor(input: MenuDto) {
    this.validate(input);
    this.id = input.id;
    this.name = input.name;
  }
  
  // 하략...
}

 

세번째 시도

검색해보니 다행히 나와 똑같은 이슈를 겪은 사례가 있었다.

 

TypeError: Issues in constructor · Issue #1590 · typeorm/typeorm

Issue type: [ ] question [x ] bug report [ ] feature request [ ] documentation issue Database system/driver: [ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [x ] postgres [ ] sqlit...

github.com

공식 문서에도 같은 말이 적혀있다.

엔티티의 경우 생성자 파라미터는 반드시 Optional 이어야 한다.
ORM 데이터베이스는 엔티티들을 불러올 때 클래스들의 인스턴스를 생성하는데, 이때 생성자의 인자 등을 인식하지 못해 무엇을 넣어야 할지 모르기 때문이다.

따라서 인자값에 Optional을 명시하고 값이 있을 때만 할당을 해준다. 따라서 처음 코드를 아래와 같이 바꿔야 한다.

 

@Entity({ name: 'menu', synchronize: true })
export class Menu {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;
  
  // 바뀐 생성자
  constructor(input?: MenuDto) {
    if (input) {
      this.validate(input);
      this.id = input.id;
      this.name = input.name;
    }
  }
  
  // 하략...
}