styled-componentsをTSで使うケースは多いですが、意外とまとまった記事がなく、聞かれることが多いのでかきました。
propsに型をつける
親が特定のreact componentでないときは、下記のようにシンプルに書くのがおすすめです。
const Button = styled.button<{primary: boolean}>`
color: ${({primary}) => primary ? 'skyblue' };
`
コンポーネントが複雑になったり親のpropsを参照する場合は、Pickを使うとメンテコストが下がることがあります
interface Props {
primary
secondary
// 略
}
function MyComponent(props: Props) {
return (
<div>
<Button secondary={props.secondary} primary={props.primary}>{props.children}</Button>
</div>
)
}
const Button = styled.button<Pick<Props, 'primary' | 'secondary'>>`
${({primary, secondary}) => primary ? css`` : secondary ? css`` : css``}
`
定数に型をつける
色やサイズなどの定数に型を付けると、利用するときにどのpxが適用されるのかがわかって便利です。
const FONT = {
XXXLARGE: 32,
XXLARGE: 24,
XLARGE: 18,
LARGE: 16,
MEDIUM: 14,
BASE: 12,
SMALL: 11,
XSMALL: 10,
TINY: 8,
} as const
const FONT_WEIGHT = {
NORMAL: 400,
BOLD: 600,
} as const
const BORDER_RADIUS = 4 as 4
export default {
FONT,
FONT_WEIGHT,
BORDER_RADIUS
}
このようにすることで、↓エディタのsuggestion機能でどの定数がどのpxを持っているかを確認することが出来ます。
css propを使うとき
babel-pluginや、babel macroで有効になるcss propは、jsxの拡張になるため何もしないとTSに怒られます。
type rootのindex.d.tsで下記を記述すれば解決します。(styled-components/csspropはreactの拡張をしています)
import {} from 'styled-components/cssprop'
attrsを使うとき
これはちょっと面倒な書き方をしなければいけないので、そもそもattrsを多用しないのもありかもしれません。
const StyledImg = styled.img.attrs<{ logoSrc: logoSrc }>(
({logoSrc}) => ({
src: logoSrc,
})
)<{ logoSrc: logoSrc }>``