1
0

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.

get(key)等の引数に補完を利かせるTypeScript (メモ)

1
Posted at

TypeScript でキー/バリューを与えたら、get(キー) のキーで補完が効く&TSチェック入る、というクラスの作り方。具体的には、下記のようなことが可能なクラスをの作成方法。

    const a = new CompletionMap({
        aa: 1,
        bb: 2,
    })

    // 補完が効いて、'aa', 'bb' が選択可能になる
    a.get('aa')
    a.get('bb')

    // 値の書き換えも可能
    a.put('bb', 22)

    // 未知のキーはTS的に怒られる
    a.get('cc')
    a.put('cc', 3)

    // キー/バリューを加えることもできる
    const b = a.mergeValues({ cc: 3 })

    // 補完が効いて、'aa', 'bb', 'cc' が選択可能になる
    b.get('aa')
    b.get('bb')
    b.get('cc')

    // これは怒られる
    b.get('dd')

方法:

export declare type CMValue = any
export declare type CMKeyValues = { [key: string]: CMValue }

class CompletionMap<T extends CMKeyValues> {
    constructor (
        public _data: T = {} as T
    ) {
    }

    get (key: keyof T): CMValue {
        return this._data[key]
    }

    put (key: keyof T, value: CMValue) {
        this._data[key] = value
    }

    /**
     * 引数で追加のオブジェクトを受け取って、マージしたオブジェクトを返す
     */
    mergeValues<T2 extends CMKeyValues> (additions: T2): CompletionMap<T & T2> {
        return new CompletionMap<T & T2>({ ...this._data, ...additions })
    }

    /**
     * 引数でインスタンスを受け取る場合
     */
    static mergeInstance<U extends CompletionMap<CMValue>, T2 extends CMKeyValues> (
        instance: U,
        additions: T2
    ): CompletionMap<U['_data'] & T2> {
        return new CompletionMap<U['_data'] & T2>({ ...instance._data, ...additions })
    }
}

test('test', () => {
    const a = new CompletionMap({
        aa: 1,
        bb: 2,
    })
    expect(a.get('aa')).toBe(1)
    expect(a.get('bb')).toBe(2)
    // expect(a.get('cc')).toBe(3)
    a.put('bb', 22)
    expect(a.get('bb')).toBe(22)

    const b = a.mergeValues({ dd: 4 })
    expect(b.get('aa')).toBe(1)
    expect(b.get('bb')).toBe(22)
    // expect(b.get('cc')).toBe(3)
    expect(b.get('dd')).toBe(4)

    const c = new CompletionMap({
        ...a._data,
        cc: 3,
    })
    expect(c.get('aa')).toBe(1)
    expect(c.get('bb')).toBe(22)
    expect(c.get('cc')).toBe(3)
    // expect(c.get('dd')).toBe(4)

    const d = CompletionMap.mergeInstance(a, { dd: 4 })
    expect(d.get('aa')).toBe(1)
    expect(d.get('bb')).toBe(22)
    // expect(d.get('cc')).toBe(3)
    expect(d.get('dd')).toBe(4)
})
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?