この記事では,以下のサイトを解説をします.
自分が自習時に作成したプログラムとサイトは,以下になります.
「React-Tutorial: Tic-Tac-Toe / 三目並べ」にTypeScriptで取り組みました.
その時に自分が分からなかった箇所,詰まった箇所を中心に解説をします.
はじめに
「React-Tutorial: Tic-Tac-Toe / 三目並べ」は,ゲームを作りながら学べるReact初心者向けサイトです.
サイトで記述されている言語は,JavaScriptです.
サイトの言語がJavaScriptなのにTypeScriptで挑んだため,色々な警告やエラーに直面しました.
React,TypeScript未経験の自分がいきなりチュートリアルに挑んだ時,欲しかった解説を残しておきます.
ローカルでTypeScriptプロジェクトを起動
チュートリアルに入る前に,ローカルでTypeScriptプロジェクトを起動します.
まず,以下からNode.jsをダウンロードします.
そして,以下のコマンドを実行します.
npm install -g npx
npx create-react-app react-tutorial --template typescript
cd react-tutorial
npm start
エラーを確認
チュートリアルで利用・編集するのは,react-tutorial/src/App.tsx
です.
例として,プログラムの全文(import React ... default App;
)を以下に書き換えます.
export default function App() {
return <p> Hello world! </p>
}
画面が以下のように変化します.
次に,同じくApp.tsx
の全文をチュートリアルの最初に出てくるApp.js
(116行)に書き換えます.
画面が以下のように変化します.
「完成したときにどのような見た目になるか、以下で確認できます。」というプログラムを利用したのに9件のエラーが出てきます.
JavaScriptでは許容されるがTypeScriptでは許容されない記述がエラーとして出ています.
完成したときの見た目はチュートリアルのサイトで確認することにして,先に進みましょう.
チュートリアルに挑戦
チュートリアルを読み進め,途中に出てくるプログラムでApp.tsx
を書き換えます.
例えば,以下のプログラムで以下の画面が出てきます.
export default function Square() {
return (
<>
<button className="square">X</button>
<button className="square">X</button>
</>
);
}
react-tutorial/src/index.css
を編集し,margin: 0;
の記述を削除,styles.css
の内容を追記すると,画面表示がチュートリアルのサイトと同じになります.
引数の型に関するエラーを修正1(05.tsx)
チュートリアルを進めていくと,以下のエラーが出ます.
Binding element 'value' implicitly has an 'any' type.
これは,関数Square
の引数value
の型が指定されていないために起きたエラーです.
1行目を以下のように書き換えて,型情報を追加するとエラーが解消されます.
- function Square({ value }) {
+ function Square({ value }: { value?: string }) {
ここで選択候補となるvalue
の型は,4種類あります.
VSCode上でvalue
にカーソルを合わせた時に表示される情報は,以下になります.
-
{ value }: { value: any }
➡(parameter) value: any
-
{ value }: { value?: any }
➡(parameter) value: any
-
{ value }: { value: string }
➡(parameter) value: string
-
{ value }: { value?: string }
➡(parameter) value: string | undefined
1, 3番目の型は,プログラムの9行目以降でエラーが出ます.
Property 'value' is missing in type '{}' but required in type '{ value: any; }'.
関数Square
の引数value
が必須にも関わらず,その値が無いためにエラーが発生しています.
<Square value="1" />
のように書き換えていくとエラーが解消されます.
2, 4番目の型はundefined
を許容しており,関数Square
の引数value
が無くても問題ないため,エラーが出ません.
JavaScriptやTypeScriptにおいて,value
の後の?
(クエスチョンマーク,疑問符)はオプションパラメータと呼び,重要な意味があります.
関数の引数やインターフェースのプロパティを省略可能であることを意味します.
JavaScriptではなくTypeScriptを利用しているので,その作法に則り,なるべく厳密に型を指定します.
{ value }: { value?: any }
は,なるべく使わないようにします.
初めは{ value }: { value?: string }
と記述し,後ほど{ value }: { value: string }
にリファクタリングするのがお勧めです.
useStateの型に関するエラーを修正(08.tsx)
チュートリアルを進めていくと,以下のエラーが出ます.
Argument of type '"X"' is not assignable to parameter of type 'SetStateAction<null>'.
これは,関数Square
の引数value
の型が指定されていないために起きたエラーです.
1行目を以下のように書き換えて,型情報を追加するとエラーが解消されます.
これは,useState
で利用するvalue
の型が指定されていないために起きたエラーです.
useState
に関する行を以下のように書き換えて,型情報を追加するとエラーが解消されます.
- const [value, setValue] = useState(null);
+ const [value, setValue] = useState<string | null>(null);
VSCode上でvalue
にカーソルを合わせた時に表示される情報は,const value: string | null
に変化します.
JavaScriptとTypeScriptでは,undefined
とnull
は異なる型です.
null
型をundefined
型で代用できる場合は,const [value, setValue] = useState<string>();
に書き換えても問題ありません.
引数の型に関するエラーを修正2(10.tsx)
チュートリアルを進めていくと,以下のエラーが出ます.
Binding element 'value' implicitly has an 'any' type.
Binding element 'onSquareClick' implicitly has an 'any' type.
これは,関数Square
の引数value
とonSquareClick
の型が指定されていないというエラーです.
引数が2つ以上ある場合,以下のように型エイリアス(Type Alias)を使うことが一般的です.
+ type Props = {
+ value: string,
+ onSquareClick?: React.MouseEventHandler<HTMLButtonElement>,
+ }
- function Square({ value, onSquareClick }) {
+ function Square({ value, onSquareClick }: Props) {
return (
<button className="square" onClick={onSquareClick}>
{value}
</button>
);
}
type Props = {...}
が型エイリアスです.
型エイリアスを使わずにSquare()
の括弧内に型を書いてもエラーが消えますが,可読性や変数の再利用を考慮すると非推奨です.
引数の型に関するエラーを修正3(12.tsx, 14.tsx, 16.tsx)
チュートリアルを進めていくと,以下のエラーが出ます.
Parameter 'i' implicitly has an 'any' type.
Parameter 'squares' implicitly has an 'any' type.
Parameter 'nextSquares' implicitly has an 'any' type.
これらの修正には,型エイリアスを使わなくても良いと思います.
以下のように変更します.
- function handleClick(i) {
+ function handleClick(i: number) {
- function calculateWinner(squares) {
+ function calculateWinner(squares: string[]) {
- function handlePlay(nextSquares) {
+ function handlePlay(nextSquares: string[]) {
引数の型に関するエラーを修正4(17.tsx, 19.tsx)
チュートリアルを進めていくと,再び引数の型に関するエラーが出てきます.
新しくBoardProps
を作成して,エラーを修正します.
+ type BoardProps = {
+ xIsNext: boolean,
+ squares: string[],
+ onPlay: (nextSquares: string[]) => void,
+ }
- function Board({ xIsNext, squares, onPlay }) {
+ function Board({ xIsNext, squares, onPlay }: BoardProps) {
関数jumpTo
を以下のように修正します.
- function jumpTo(nextMove) {
+ function jumpTo(nextMove: number) {
以上の情報があれば,TypeScriptで「React-Tutorial: Tic-Tac-Toe / 三目並べ」が完了できます.
終わりに
この記事で紹介したチュートリアルは,Reactを実践しながら学ぶことができ,実際にweb画面で動くものが作れるお勧めの教材です.
JavaScriptを利用するのであれば,この記事に記載したエラーに直面することなく,チュートリアルのwebサイトだけでスムーズに学習できると思います.
開発環境がTypeScript × Reactの場合,この記事を参考にしながらチュートリアルに取り組んでみてはいかがでしょうか.
JavaScriptとTypeScriptの違いも勉強できて,一石二鳥です.
関連記事: