📑

(続)classnamesライブラリをより型安全に利用する

2021/10/12に公開

前回の記事で、classnames-genericsを利用して、classnamesをより安全に利用する方法を紹介しました。ReactでCSS Modulesを利用してスタイリングをする場合は、これだけでは不十分です。

以下のようなコンポーネントがあったとします。

header/index.tsx
import React, {VFC} from 'react';
import styles from './index.module.scss'

type Props = {
  active: boolean;
}

export const Header: VFC = (props) => {
  return (
    <header className={`header ${props.active ? 'active' : ''}`}>
      続)classnamesライブラリをより型安全に利用する
    </header>
  )
}
header/index.module.scss
.header {
  background-color: red;
  .active {
    background-color: black;
  }
}

前回の記事にも紹介したように、(https://zenn.dev/j1ngzoue/articles/77f757ee57935d)で、classnames-genericsを利用して、classNameに設定する値を型安全に利用します。

header/index.tsx
import React, {VFC} from 'react';
import styles from './index.module.scss'
import {classNamesFunc} from 'classnames-generics'

type HeaderClassName = 'header' | 'active';
type Props = {
  active: boolean;
}
const classNames = classNamesFunc<HeaderClassName>();

export const Header: VFC = (props) => {
  return (
    <header 
      className={classNames(styles.hader, {[styles.active]: props.active})}>
      続)classnamesライブラリをより型安全に利用する
    </header>
  )
}

のようにしたいところですが、./index.module.scssで読み込んだ styles の型が不明なためエラーとなってしまいます。
./index.module.scssの型を用意して解決してみます。

index.module.scss.d.ts
export const header = 'header'
export const active = 'active'
header/index.tsx
import React, {VFC} from 'react';
import styles from './index.module.scss'
import {classNamesFunc} from 'classnames-generics'

type HeaderClassName = keyof typeof styles;
type Props = {
  active: boolean;
}
const classNames = classNamesFunc<HeaderClassName>();

export const Header: VFC = (props) => {
  return (
    <header 
      className={classNames(styles.hader, {[styles.active]: props.active})}>
      続)classnamesライブラリをより型安全に利用する
    </header>
  )
}

scssファイルの型を用意することで、classNamesに設定する値を型安全にすることができました。ただ、この方法は、scssファイルの型を用意する必要があるので、その分のコストを考える必要がありそうです。

Discussion