
class User{
id = 1;
//id;
}
const user = new User();
console.log(user.id) // 1
//console.log(user.id) //undefined
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 하여 사용하는 것 같다.)
이전에는 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...
}