Typescript
基本的な型
TypeList.ts
// boolean
let bool: boolean = true;
console.log(bool);
// number
let num:number = 0;
console.log(num);
//string
let str:string = "A";
// Array
let arr1:Array<number> = [0, 1, 2];
console.log(arr1);
let arr2:number[] = [3, 4, 5];
console.log(arr2);
// tuple
let tuple: [number, string] = [0, "A"];
console.log(tuple);
// any
let any1: any = false;
console.log(any1);
// void 戻り値がない
const funcA = (): void => {
const test = "text";
console.log(test);
};
funcA();
// null
let null1: null = null;
console.log(null1)
// undefined
let undefined1:undefined1 = undefined
console.log(undefined1);
// object
let obj1: object = {};
console.log(obj1);
let obj2: {id: number, name: string} = {id: 1, name: "A"};
console.log(obj2);
引数の型指定
Argument.tsx
import React from 'react';
const Argument = () => {
const calcTotalFee = (num:number):void => {
const total:number = num * 1.1;
console.log(total);
}
const onClickPractice = ():void => {
calcTotalFee(1000);
};
return (
<div>
<p>引数の型指定</p>
<button onClick={onClickPractice}>練習問題1</button>
</div>
);
};
export default Argument;
Reactに型定義
型管理
types/todo.ts
export type TodoType = {
userId: number,
id: number,
title: string,
completed: boolean
}
types/user.ts
export type User = {
name: string,
hobbies?: Array<string>
}
hobbies?: Array<string>
hobbies"?"は入れがない場合を許容する
コンポーネント
App.tsx
App.tsx
import './App.css'
import axios from "axios";
import {useState} from "react";
import Todo from "./Todo.tsx";
import {TodoType} from "./types/todo.ts";
import Text from "./Text.tsx";
import {User} from "./types/user.ts";
import UserProfile from "./UserProfile.tsx";
// type TodoType = {
// userId: number,
// id: number,
// title: string,
// completed: boolean
// }
const user:User = {
name: "yukilulu0229",
hobbies: ["Guitar", "Programing", "React"]
}
function App() {
const [todos, setTodos] = useState<Array<TodoType>>([])
const onClickFetchData = () => {
axios.get<Array<TodoType>>("https://jsonplaceholder.typicode.com/todos/").then((res) => {
// console.log(res.data.userId)
setTodos(res.data);
})
};
return (
<>
<button onClick={onClickFetchData}>データ取得</button>
{todos.map((todo) => (
<Todo key={todo.id} title={todo.title} userId={todo.userId} completed={todo.completed} />
))}
<Text color={"red"} fontSize={"44px"}/>
<UserProfile user={user}/>
</>
)
}
export default App
const [todos, setTodos] = useState<Array<TodoType>>([])
- [todos, setTodos]なので Array
- TodoTypeはtypes/todo.tsから読み込んでる
axios.get<Array<TodoType>>
APIが配列型だからArray
<Todo key={todo.id} title={todo.title} userId={todo.userId} completed={todo.completed} />
Todoコンポーネントに渡したいもの
const user:User = {
name: "yukilulu0229",
hobbies: ["Guitar", "Programing", "React"]
}
Userはtypes/user.tsからインポートしている
<UserProfile user={user}/>
userのオブジェクトごと渡している
Todo.tsx
Todo.tsx
import React, {FC} from 'react';
import {TodoType} from "./types/todo.ts";
// type TodoType = {
// userId: number,
// title: string,
// completed?: boolean // ?をつけるとundefinedも許容
// }
// const Todo = (props: Pick<TodoType, "userId" | "title" | "completed">) => {
// const Todo = (props: Omit<TodoType, "id">) => {
const Todo: FC<Omit<TodoType, "id">> = (props ) => {
const {title, userId, completed = false} = props;
const completedMark:string = completed ? "[完了]" : "[未完了]"
return (
<div>
<p>{`${completedMark}${title} (user: ${userId})`}</p>
</div>
);
};
export default Todo;
import {TodoType} from "./types/todo.ts";
todo.tsの型定義をimport
const Todo = (props: Pick<TodoType, "userId" | "title" | "completed">) => {
PickでTodoTypeの有効化する型定義
const Todo = (props: Omit<TodoType, "id">) => {
OmitでTodoTypeの無効化する型定義
const Todo: FC<Omit<TodoType, "id">> = (props ) => {
FCは関数型コンポーネントに使う
Text.tsx
Text.tsx
import React, {FC} from 'react';
type Props = {
color: string,
fontSize: string,
}
// 関数型コンポーネント場合はFC
const Text: FC<Props> = (props) => {
const {color, fontSize} = props
return (
<div>
<p style={{color, fontSize}}>Text file</p>
</div>
);
};
export default Text;
const Text: FC<Props> = (props) => {
FCは関数型コンポーネントに使う
UserProfile.tsx
import React, {FC} from 'react';
import {User} from "./types/user.ts";
type Props = {
user: User
}
const UserProfile: FC<Props> = (props) => {
const {user} = props;
return (
<dl>
<dt>名前</dt>
<dd>{user.name}</dd>
<dt>趣味</dt>
<dd>{user.hobbies?.join(" / ")}</dd>
</dl>
);
};
export default UserProfile;
type Props = {
user: User
}
Userをインポートして型定義している
<dd>{user.hobbies?.join(" / ")}</dd>
hobbies?でnullやundefinedば場合は後ろの .joinを実行しない
オプショナルチェインという
ライブラリの型定義
package.json
{
"name": "react_jakey_02",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.6.7",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.55.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"typescript": "^5.2.2",
"vite": "^5.0.8"
}
}
"@types/react-dom": "^18.2.17",
などは型定義されているない場合は
@types/foobarを探す
GitHubをみてfoobar.d.tsがあれば型定義されていることが多い