React Bootstrapは、Bootstrapのスタイルが適用されたコンポーネントをReactアプリケーションに組み込めるライブラリです。今年3月24日に正規バージョンv1.0.0がリリースされ、4月23日には1.0.1にアップデートされました。Bootstrapのみでは<div>などにやたらとクラスを詰め込んだDOM要素があふれます。それに対して、アプリケーションをReactのコンポーネントですっきりと組み立てられるのが利点です。
ButtonコンポーネントのプロパティをJavaScript形式で定める
山盛りのクラスと<div>
の入れ子を書くことなく、設定はタグの属性(プロパティ)で済ませられたりします。Button
コンポーネントのテキストやカラーテーマ(variant
)、大きさ(size
)なども、JavaScript形式(js
ファイル)のコードでつぎのように動的に定められます(図001)。
import React from 'react';
import { Container, Button } from 'react-bootstrap';
function App() {
const buttonProps = {
text: 'Button Text',
variant: 'success',
size: 'lg',
};
return (
<div>
<Container>
<Button
variant={buttonProps.variant}
size={buttonProps.size}
>
{buttonProps.text}
</Button>
</Container>
</div>
);
}
export default App;
図001■ButtonコンポーネントのプロパティをJavaScriptコードで定めた
ButtonコンポーネントのプロパティをTypeScript形式で定める
前掲のJavaScriptコードを、TypeScript形式(tsx
ファイル)にそのままコピーしてみましょう(TypeScript形式のひな形Reactアプリケーションのつくり方については「Create React App + TypeScript: 関数コンポーネントにTypeScriptで型づけする」をお読みください)。たちまち、えらい剣幕で怒られます(図002)。
図002■プロパティの指定が型に合わないというエラーメッセージ
プロパティ(variant
とsize
)がとれる値(文字列)は決まっています。そのため、それら特定の文字列が型として定められているからです。使う値を型エイリアスtype
で宣言してしまえばよいでしょう。そのうえで、変数にas
を用いて型変換(キャスト)します。
type variant =
| 'primary'
| 'secondary'
| 'success'
| 'danger'
| 'warning'
| 'info'
| 'dark'
| 'light'
| 'link'
| 'outline-primary'
| 'outline-secondary'
| 'outline-success'
| 'outline-danger'
| 'outline-warning'
| 'outline-info'
| 'outline-dark'
| 'outline-light'
;
type size = 'sm' | 'lg';
function App() {
/* ...[中略]... */
return (
<div className="App">
<Container>
{/* <Button
variant={buttonProps.variant}
size={buttonProps.size}
> */}
<Button
variant={buttonProps.variant as variant}
size={buttonProps.size as size}
>
{buttonProps.text}
</Button>
</Container>
</div>
);
}
ButtonProps
インタフェースを使う
エラーメッセージからソースを探ると、ButtonProps
がインタフェースだとわかります。したがって、このインタフェースをimport
すれば、型づけできるということです。
ただし、ドットアクセスButtonProps.variant
で型を得ることはできません。つぎのような警告が示されるでしょう。型はブラケット参照ButtonProps['variant']
で取り出さなければならないのです。
'ButtonProps.variant' にアクセスできません。'ButtonProps' は型で、名前空間ではありません。'ButtonProps["variant"]' で 'ButtonProps' のプロパティ 'variant' の型を取得するつもりでしたか?
インタフェースButtonProps
で型をキャストしたのが、つぎのコードです。サンプルをCodeSandbox「React Boostrap + TypeScript: Dynamically changing Button properties」に公開します。
import React from 'react';
import {
Container,
Button,
ButtonProps,
} from 'react-bootstrap';
function App() {
const buttonProps = {
text: 'Button Text',
variant: 'success',
size: 'lg',
};
return (
<div className="App">
<Container>
<Button
variant={buttonProps.variant as ButtonProps['variant']}
size={buttonProps.size as ButtonProps['size']}
>
{buttonProps.text}
</Button>
</Container>
</div>
);
}
export default App;