93
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React.FC 型を拡張する

Last updated at Posted at 2019-03-12

雰囲気で使わない @types/react の続編です。自分もそうなのですが、多くのプロジェクトで styled-components が利用されているかと思います。この時、お決まりの様に Props型に className?: string を差し込んでいました。

import * as React from 'react'

type Props = {
  className?: string
  label: string
  onClick: (props?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
}

const View: React.FC<Props> = props => (
  <p className={props.className}>
    <button onClick={props.onClick}>{props.label}</button>
  </p>
)

export default styled(View)`
background-color: #f00;
`

これを省略するために、掲題の通り、React.FC型を拡張します。拡張といっても、別の型を用意して、declare module に新しい型を追加するだけです。まずは、React.FC型の元定義を確認。

@types/react/index.d.ts
type FC<P = {}> = FunctionComponent<P>;

プロジェクトの任意の場所に、以下の通り定義を追加します。型名称は何でも良いのですが、FCX型とします。Intersection Types で { className?: string } を注入します。

src/type.ts
import * as React from 'react'
declare module 'react' {
  type FCX<P = {}> = FunctionComponent<P & { className?: string }>
}

FCX型を使う

module の型定義に追加しているため、React.FCX で参照できます。これで、冗長な className?: string 宣言を省略できる様になりました :tada:

import * as React from 'react'

type Props = {
  label: string
  onClick: (props?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
}

const View: React.FCX<Props> = props => (
  <p className={props.className}> {/* No Error! */}
    <button onClick={props.onClick}>{props.label}</button>
  </p>
)

export default styled(View)`
background-color: #f00;
`
93
55
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
93
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?