LoginSignup
8
6

More than 3 years have passed since last update.

TypeScript: デコレータでobject.toString()の結果を[object Object]ではなく[object クラス名]にする方法

Last updated at Posted at 2019-10-30

JavaScriptでは、クラスをnewして作ったオブジェクトを.toString()しても'[object Object]'が戻り値になる。

この戻り値を、デコレーターを用いて[object クラス名]に変える方法を紹介する。

Object.prototype.toStringを上書きする必要はない

通常、コンストラクタが返す値は、Objectを継承しているので、toStringメソッドが生えている。toStringの結果を変えようとするなら、Object.prototype.toStringをオーバーライドする方法が思いつくが、その必要はない。Object.prototype.toString[object Object]を返すのはデフォルトの振る舞いで、この戻り値のObjectの部分だけを変更する仕組みがあるからだ。

Symbol.toStringTagを使う

オブジェクトに[Symbol.toStringTag]プロパティがあると、Object.prototype.toString"Object"よりも、そのプロパティの値を尊重してくれる。

class Foo { } // 通常のクラス

class Bar {
    [Symbol.toStringTag] = 'Bar'
}

console.log(new Foo().toString()) //=> [object Object]
console.log(new Bar().toString()) //=> [object Bar]

参考: Symbol.toStringTag - JavaScript | MDN

Symbol.toStringTagをデコレータで実現する

クラスごとに[Symbol.toStringTag]を実装するのは面倒なので、デコレータで実現する方法を紹介する。

次のコードのautotagはクラスデコレータの実装で、デコレートされたクラスに[Symbol.toStringTag]プロパティを生やす。

// デコレータの定義
const autotag: ClassDecorator = constructor => {
    constructor.prototype[Symbol.toStringTag] = constructor.name
    return constructor
}

使い方としては、クラスの手前に@autotagと書くだけ。これで、クラスに[Symbol.toStringTag]を実装したのと同じ効果が得られる。

// 普通のクラス
class Foo { }

// デコレータを使ったクラス
@autotag
class Bar { }

console.log(new Foo().toString()) //=> [object Object]
console.log(new Bar().toString()) //=> [object Bar]

8
6
0

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
8
6