解決したいこと
下記のような、自前のテーマを持っていたとして、
export type OurTheme = {
ourSuperAwesomeColor: string
}
emotionで、下記のようなstyled-componentなコードを書きたい場合、型エラーでコンパイルが通りません。
// TypeScript「 `({theme})` の型がわかりましぇ〜ん!」
const AwesomeHeading = styled.h1`
color: ${ ({theme}) => theme.ourSuperAwesomeColor };
`
さて、どうすればいいでしょうか。
キャストは嫌だ
もちろん、下記のようなダサいことをすれば通るんですが、コードのそこかしこに同じような ゴミ キャストを撒き散らすと考えると微妙です。
const AwesomeHeading = styled.h1`
color: ${ ({theme}) => (theme as OurTheme).ourSuperAwesomeColor };
`
あなた知らないの? styled.**
は実は省略可能な型変数を持っていて、省略されている型変数の2番目をきちんと指定すればテーマの型を指定できるよ?
なるほど…??
const AwesomeHeading = styled.h1<ここに入れる型がわからない, OurTheme>`
color: ${ ({theme}) => theme.ourSuperAwesomeColor };
`
ここに入れる型がわからない
の型変数(本来はpropsの型を示すところでした)の記載を省略したいのですが、TypeScriptでは残念なことに今のところは省略可能な任意の位置の型変数を省略したままにする術がありません。
あー困った困った…
(ちなみに型がわからないからといって any
とか入れると、一気に型チェック無しの世界に入るので、やめたほうがいいです。)
仕方ないので、自前で styled
を用意する
ということで、私は自前で styled
を用意することにしました。
// `@emotion/styled-base` から import しないように注意
import styled, { CreateStyled } from "@emotion/styled";
// 既存の `styled` をそのまま別の型として見るだけの変数を宣言。
export const ourStyled: CreateStyled<OurTheme> = styled;
上記のようなものを用意しておくと、下記のように書けます。
const AwesomeHeading = ourStyled.h1`
color: ${ ({theme}) => theme.ourSuperAwesomeColor };
`
これでスッキリ!