typescript-sequelize(class 방식)

JuhyeokLee·2022년 5월 30일
post-thumbnail

Class

  • 일반적으로 클래스를 작성할 때 특정 property를 public으로 선언하게 될 경우 new 키워드를 사용하여 접근할 수 있다.
class User{
	id = 1;
	//id;
}

const user = new User();
console.log(user.id) // 1
//console.log(user.id) //undefined

Sequelize에 Typescript 적용하기

Sequelize < 6.14.0

  • Model에 들어가는 attributes를 직접 타입을 설정하여 제네릭 방식으로 지정해주어야 한다.
  • declare 키워드를 사용하면, model의 attribute의 타입 정보를 public class field를 추가하지 않고 선언할 수 있다.
    • Typescript가 컴파일 한 파일에서 보면 declare로 선언된 field는 class 내에서 public field로 선언되어 있지 않다.
    • 즉, declare는 typescript에서 타입을 지정해주기 위해서 사용된다.
      ( js에선 존재하지 않는 키워드이다.)
import { Optional } from "sequelize";

type UserAttributes = {
  id: number,
  name: string,
  // other attributes...
};

// User 모델에서 자동으로 생성되는 Attribute는 Optional을 이용하여 선언한다.
// ex) id, createdAt, updatedAt ...
type UserCreationAttributes = Optional<UserAttributes, 'id'>;

class User extends Model<UserAttributes, UserCreationAttributes> {
  declare id: number;
  declare string: number;
  // other attributes...
}
User.init({
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true
  }
}, { sequelize });

// id field를 선언해주지 않았더라도 1이 나오는 모습(declare는 단순히 타입선언)
const user = new User({ id: 1 });
user.id; // 1

여기까지 정리내용

  • 우리가 클래스 내에서 field값을 선언하지 않았다면, 객체를 만들고 해당 field값을 접근하고자 할 때 undefined가 나온다. (class 정리 참고!)
  • declare로 선언한 필드값은 Typescript에서 field 값으로 선언한 것이 아닌 타입지정을 위해서 사용된다. 그 증거로 complie 후에 declare로 선언된 필드는 class에 추가되어 있지 않다.
    ( 실제 js에는 declare라는 키워드가 존재하지 않는다.)
  • init method를 사용한다면, 객체 생성 시에 넘긴 값을 통해서 객체를 생성하고 해당 객체의 field 값에 접근 가능하다.
    (sequelize의 Model 내부적으로 init 메소드를 가지고 있고 그 메소드를 extends 하여 사용하는 것 같다.)

Sequelize >= 6.14.0

  • 이전에는 Model에서 사용할 타입을 직접 만들어서 제네릭 방식을 통해 넣어줘야 했지만, 6.14.0 이후에는 InferAttributes, InferCreationAttributes를 사용하여 class에 선언된 필드값을 통해 자동으로 타입을 선언한다.

  • 이전에는 자동으로 만들어지는 attributes에 대해서 Optional을 사용했지만 6.14.0 이후 버전에는 CreationOptional을 사용한다. 단, null이나 undefined가 가능한 attributes는 사용하지 않아도 된다.

import { Model, InferAttributes, InferCreationAttributes, CreationOptional } from 'sequelize';

// order of InferAttributes & InferCreationAttributes is important.
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  // 'CreationOptional' is a special type that marks the field as optional
  // when creating an instance of the model (such as using Model.create()).
  declare id: CreationOptional<number>;
  declare name: number;
  // other attributes...
}
profile
성장하는 개발자가 되겠습니다~

0개의 댓글