6
3

Nodeのビルドインオブジェクトを拡張する

Last updated at Posted at 2024-03-19

目的

配列のremoveメソッドなど、JSのビルトインオブジェクトには存在しないメソッドを拡張して定義したい

問題点

こんな感じで関数を定義してもいいけど、

function remove<T>(array: T[], removeElement: T): T[] {
    return array.filter(element => element !== removeElement)
}

remove(['a', 'b', 'c'], 'b') // ['a', 'c']

やっぱり配列のメソッドとして拡張ができた方が、使いやすいし読みやすい。
swiftならextensionで、Kotlinなら関数の前にレシーバータイプを記述することで拡張関数を定義できる。
しかしTypescriptにはそのような文法はない。

解決策

まず配列のアンビエント宣言を追加し、型チェックができるようにする。
その後配列のprototypeオブジェクトに任意の名前で関数を代入する。

export {}

declare global {
    interface Array<T> {
        remove<T>(removeElement: T): T[];
    }
}

Array.prototype.remove = function<T>(removeElement: T): T[] {
    return this.filter(element => element !== removeElement)
}

あとはviteのReactプロジェクトの場合であれば、ルートであるmain.tsxでインポートすることで、
グローバルに使えるようになる。

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './ArrayExtensions.ts' // 追加


ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
        <App/>
    </React.StrictMode>,
)

テスト実行時も動作するように、setupTestsでもインポートしておく

import '@testing-library/jest-dom/vitest'
import userEvent from '@testing-library/user-event'
import { render } from '@testing-library/react'
import '../ArrayExtensions.ts' // 追加

export default function setup(jsx: JSX.Element) {
    return {
        user: userEvent.setup(),
        ...render(jsx)
    }
}

完成

['a', 'b', 'c'].remove('b') // ['a', 'c']
6
3
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
6
3