目的
配列の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']