Open8
TypeScript入門
厳密な型指定
TypeScriptはjavaScriptに型指定を導入してくれる
型指定が無いのはいいこともあれば悪いこともある
typeList.tsx
/* eslint-disable */
/** TypeScriptの基本の型 */
// boolean
let bool: boolean = true;
// number 数値
let num: number = 0;
// string 文字
let str: string = "A";
// array 配列
let arr1: Array<number> = [0, 1, 2];
let arr2: number[] = [0, 1, 2];
// tuple
let tuple: [number, string] = [0, "A"];
// any なんでも良い
let any1: any = false;
// void 関数
// 何も書かなければvoidと認識する
const funcA = (): void => {
const test = "TEST";
};
// null
let null1: null = null;
// undefined 何も設定されてない
let undefined1: undefined = undefined;
// object
let obj1: object = {};
let obj2: { id: number; name: string } = { id: 0, name: "name" };
つまり?
これはエラーにならない
しかし、以下のようにcalcTotalFeeの引数に型指定を与えることによって、文字列を渡そうとしている部分でエラーが起きている。これは厳密な型指定のお陰なのだ。のだのだ。
戻り値の型を決めよう
引数の後に: numberなどとして指定する
画像のように、returnの型をstringにしようとするとエラーが起きる
変数の型を指定する
let total: numberと型をnumberにしてるので、total.toStringが返ってきて代入しようにもエラーになっている
型定義
TypeScriptの真骨頂、型定義!!
取得するデータに応じてこのような型を定義する
App.tsx
type TodoType = {
userId: number;
id: number;
title: string;
completed: boolean;
};
stateで以下のように型を指定できる。
今回データが複数配列形式で渡されるので、Array<TodoType>という型になっているのに気を付ける
App.tsx
const [todoes, setTodoes] = useState<Array<TodoType>>([]);
propsに型を指定することで、不要なバグを防ぐことができるようになる。
型名の後ろに?を付ければ、変数が渡されなくてもエラーにならない。そのため初期値を設定しておくのが良い
Todo.tsx
type TodoType = {
userId: number;
title: string;
completed?: boolean; //指定しなくてもエラーにならない
};
export const Todo = (props: TodoType) => {
// completedは渡ってこなくてもいいので初期値を設定しておく
const { title, userId, completed = false } = props;
const completaMark = completed ? "[完]" : "[未]";
return <p>{`${completaMark}${title}(ユーザー:${userId})`}</p>;
};
型定義の管理
他と同じように別ファイルに切り出せる
Todo.tsx
import { TodoType } from "./types/todo";
型をそのまま使いたくない時は、Pick,Omitというものを使える。既存の型から抽出したり省略して記述できる。
// Pick:型の中から抽出して型を使用できる
props: Pick<TodoType, "userId" | "title" | "completed">
// Omit:型の中から省略して型を使用できる
props: Omit<TodoType, "id">
全文
Todo.tsx
export const Todo = (
// Pick:型の中から抽出して型を使用できる
// props: Pick<TodoType, "userId" | "title" | "completed">
// Omit:型の中から省略して型を使用できる
props: Omit<TodoType, "id">
) => {
// completedは渡ってこなくてもいいので初期値を設定しておく
const { title, userId, completed = false } = props;
const completaMark = completed ? "[完]" : "[未]";
return <p>{`${completaMark}${title}(ユーザー:${userId})`}</p>;
};
関数の型指定 VFC※ver 17
Text.tsx
import { VFC } from "react";
// ここはいつものtype指定
type Props = {
color: string;
fontSize: string;
};
// 関数コンポーネントにはVFCを使う ※ver17
// ver18以降ではFCで良くなる。ver17ではchildrenが暗黙的に持ってしまっている
// 関数名: VFC<型>
export const Text: VFC<Props> = (props) => {
const { color, fontSize } = props;
return <p style={{ color, fontSize }}>テキストです</p>;
};
OptionalChaining
配列に要素が無い場合、エラーにしないことができる
UserProfile.tsx
type Props = {
user: User;
};
export const UserProfile: VFC<Props> = (props) => {
const { user } = props;
return (
<dl>
<dt>名前</dt>
<dd>{user.name}</dd>
<dt>趣味</dt>
{/* 配列.join(デミリタ)で、配列をデミリタで接続してストリングにする */}
{/* OptionalChaining 配列に?をつけると、要素が無い場合エラーにならず
そのまま終了する。以下の例だとhobbiesを渡さない場合何も表示されない。 */}
<dd>{user.hobbies?.join(" / ")}</dd>
</dl>
);
};
hobbiesがある場合
const user: User = {
name: "asdfajslfjals",
hobbies: ["telnet", "bombealdhie"]
};
hobbiesがない場合
const user: User = {
name: "asdfajslfjals",
// hobbies: ["telnet", "bombealdhie"]
};
使い方
<UserProfile user={user} />