7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

クラスオブジェクトの@Expose()ってなに?

Last updated at Posted at 2022-10-09

はじめに

API開発を進めていく中で、クラスオブジェクトの定義の中になにやら@Expose()という呪文が書いていたので調べてみることにしました。

また、過去にはclass-transformerの概要についても書いてみました。

plainToClass()関数

まず、(プレーンオブジェクトを要素とする)連想配列usersと独自に定義したUserクラスがあるとします。

index.ts
import { plainToClass } from "class-transformer";

const users = [
  {
    id: 1,
    firstName: "Johny",
    lastName: "Cage",
    age: 27,
  },
  {
    id: 2,
    firstName: "Ismoil",
    lastName: "Somoni",
    age: 50,
  },
  {
    id: 3,
    firstName: "Luke",
    lastName: "Dacascos",
    age: 12,
  },
];

export class User {
  id: number;
  firstName: string;
  lastName: string;
  age: number;

  getName() {
    return this.firstName + " " + this.lastName;
  }

  isAdult() {
    return this.age > 36 && this.age < 60;
  }
}

const realUsers = plainToClass(User, users);

console.log(realUsers[0].age, realUsers[0].isAdult(), realUsers[0].getName());
// 27 false Johny Cage

連想配列usersを、UserクラスにTransformすることで当該クラスのプロパティだけでなく、メソッドまで活用できるようになります。

plainToClass()関数のデフォルトの挙動の問題

index.ts
import { plainToClass } from 'class-transformer';

class User {
  id: number;
  firstName: string;
  lastName: string;
}

const fromPlainUser = {
  unknownProp: 'hello there',
  firstName: 'Umed',
  lastName: 'Khudoiberdiev',
};

console.log(plainToClass(User, fromPlainUser));

// User {
//   unkownProp: 'hello there',
//   firstName: 'Umed',
//   lastName: 'Khudoiberdiev',
// }

しかしデフォルトでは、plainToClass()関数はプレーンオブジェクトfromPlainUserの全プロパティを踏襲してきてしまいます。Userクラスにないプロパティでも上書きしてしまい、また、Userクラスにはあったidプロパティも消されてしまいました。

「型がある程度保証されたままでTransformをしたい」というのが、ここでの課題になります。

Expose()してtype-safeなインスタンス化をする

上記のデフォルトの挙動による問題を解決するために、プレーンオブジェクトの全プロパティを踏襲してしまうのではなく、Transformした後に不必要なプロパティを排除するために、excludeExtraneousValuesなるオプションをつけることができます。

index.ts
import { Expose, plainToClass } from 'class-transformer';

class User {
  @Expose() id: number;
  @Expose() firstName: string;
  @Expose() lastName: string;
}

const fromPlainUser = {
  unkownProp: 'hello there',
  firstName: 'Umed',
  lastName: 'Khudoiberdiev',
};

console.log(plainToClass(User, fromPlainUser, { excludeExtraneousValues: true }));

// User {
//   id: undefined,
//   firstName: 'Umed',
//   lastName: 'Khudoiberdiev'
// }

ここで、出力結果にほしいプロパティは、Userクラスを定義した際にあらかじめ@Expose()を宣言しておく必要があります。

最後に

自分が日頃インターンの業務で触っているソースコードを見て知らなかったところを備忘録にしてみました。この学びを共有できれば幸甚です。

参考

7
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?