こんにちは、フロントエンドエンジニアの峯です。
最近はNextJSやGatsbyJSを使ってWebページや、Webサービスの開発を行なっています。
今回は、テスト導入の第一歩!TypeScriptについてです。 テスト導入と言うとハードルが高いと感じる人も多いと思います。まずは、TypeScriptの導入から始めてみるのをお勧めします。
TypeScript未導入のButtonコンポーネントを例に、TypeScriptを導入することで、得られるメリットをご理解いただけたらと思います。
※ 具体的なTypeScriptの書き方は紹介しておりません。
目次
型未定義のコンポーネントの課題
Reactを使ったUIコンポーネント開発を行う際、以下のようなButtonコンポーネントがよくあると思います。
こちらのButtonコンポーネントは、型の安全性が担保されておらず、想定外のpropsを受け取る可能性があります。
const Button = ({ color, disable, onClick, children }) => {
return (
<button
type='button'
className={color}
disable={disabled}
onClick={onClick}
>
{children}
</button>
)
}
こちらのコンポーネントは、propsに何を渡すべきか全くわかりません。
colorには、カラーコード?それとも自由にカラー名を渡せばよいのでしょうか?
スタイル設定までしっかり確認する必要があります。
引数の安全性を担保する
先ほどのButtonコンポーネントに型を追加していきます。
interface Props extends React.ComponentPropsWithoutref<'button'> {
color?: 'primary' | 'secondary'
disable?: boolean
onClick?: () => void
children?: React.ReactNode
}
const Button = ({ color, disable, onClick, children, ...props }: Props) => {
return (
<button
type='button'
className={color}
disable={disabled}
onClick={onClick}
{...props}
>
{children}
</button>
)
}
まず、propsの型Props
を定義しています。
このように、それぞれのpropsの値に型を定義することで、どのような値を想定しているのかわかります。
例えば、colorは、primaryか、secondaryという二つの値を想定しています。disableはboolean値を想定しているのがわかります。
また、ButtonコンポーネントにReact.ComponentPropsWithoutref<'button'>
を継承させることで、<button>
のデフォルトpropsも利用することができます。
これで、Buttonコンポーネントを参照するだけで、どのような値を渡せば良いか明確になりました。
属人化しないコード運用
JavaScriptは非常に自由度の高いプログラミング言語です。
COBOLなどをやっていた私からすると、JavaScriptの書き方は千差万別です。(JavaScriptに限らないとは思いますが。)そのようなものを長期的に管理・運用していくためには、運用性や変更容易性を高める必要があります。
運用性や変更容易性を高める要素のひとつとして、「コードから意図が伝わるか」は重要です。
型を定義することで、コンポーネントに関わらず、変数やメソッドでも同様に、引数が明確化されコードの意図を見る人に伝えることができます。
仕様がわからない、どのような仕組みになっているのか理解しきれないなど、不確実性が高いほど運用性は低下し、デグレのリスクは高まります。
型通り値を渡すことができている状態は、既存の品質を維持しているといえますので、変更もより安心して行うことができるはずです。
さいごに
私自身、まだまだ運用性を重視したコーディング力に課題を感じています。チームとして高めていくための取り組みもトライの途中です。ひとりでも多くのエンジニアが未来のためにコードを書くことができれば、未来はもっと明るくなると信じて日々精進しましょう。
今回紹介したTypeScriptは、その第1歩として導入しやすいのではないかと思います。
コードを日々安全に運用するために、コツコツ安全性を高めていく運用を心がけてみてください。