2
1

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 5 years have passed since last update.

TypeScript: メソッドやゲッターの計算結果をキャッシュするデコレータ

2
Last updated at Posted at 2020-03-06

実行すると計算結果をキャッシュするデコレータがあると便利です
下記のようにかけるようになります

import { memoized } from '~/util/memoizedMethod'

class Foo {
  @memoized
  async action() {
    console.log('₍₍(ง˘ω˘)ว⁾⁾')
  }
  @memoized
  get magicNumber() {
    console.log('42')
    return 42
  }
}

const foo = new Foo()
foo.magicNumber // 42
foo.magicNumber // なにも出ない
foo.magicNumber // なにも出ない
await foo.action() // ₍₍(ง˘ω˘)ว⁾⁾
await foo.action() // なにも出ない
await foo.action() // なにも出ない

実装

const memoized = (_target: any, _propKey: string, descriptor: PropertyDescriptor) => {
  const key =
    'function' === typeof descriptor.value ? 'value' :
    'function' === typeof descriptor.get ? 'get' :
    null
  if (!key) return
  const original = descriptor[key]
  const map = new WeakMap<any, { v: any }>()
  descriptor[key] = function() {
    const r = map.get(this)
    if (r) return r.v
    const v = Reflect.apply(original, this, arguments)
    map.set(this, { v })
    return v
  }
  if ('get' === key && 'function' === typeof descriptor.set) {
    const original = descriptor.set
    descriptor.set = function() {
      Reflect.apply(original, this, arguments)
      map.delete(this)
    }
  }
}

引数を持つメソッドなどに使うとうまく動かないので型エラーが出るようにしたいけど無理っぽい?

関連

TypeScript: 計算結果をキャッシュする関数

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?