TypeScriptを基本からまとめたみた【完全入門】

## tsconfig.json Rundown

(1)フォルダとファイルを作成する

(2)Node.jsのパッケージ管理ツールであるnpm（Node Package Manager）を使用して、TypeScriptをグローバルにインストールする

```
npm install -g typescript
```

(3)TypeScriptコンパイラ(tsc)を使用して新しいTypeScriptプロジェクト用の基本的な設定ファイル(tsconfig.json)を生成する

```
tsc --init
```

## 図書館の管理アプリを作成する

(1)JavaScriptで実装する


```index.js
//本の在庫
const books = [
  { title: 'TypeScript入門', author: '田中太郎', available: true },
  { title: 'JavaScript入門', author: '山田太郎', available: false },
  { title: 'React入門', author: '鈴木太郎', available: true },
];

//借りた本をリストを保存
const borrowedBooks = [];
let newBookId = 1;

//本が入荷した時に書籍リストに追加
function addNewBook(book) {
  books.push(book);
  return book;
}

//借りたい本のタイトルを関数に渡すと貸してくれる
function borrowedBooks(title) {
  const selectedBook = books.find(
    (book) => book.title == title && book.available
  );
  selectedBook.available = false;
  const newBorrowedBook = {
    id: newBookId,
    book: selectedBook,
    status: 'borrowed',
  };
  borrowedBooks.push(newBorrowedBook);
  return selectedBook;
}

//借りた本の返却
function returnBook(bookId) {
  const selectedBook = borrowedBooks.find((book) => book.id === bookId);
  selectedBook.book.available = true;
  selectedBook.status = 'returned';
  return selectedBook;
}

//新しい本の追加
addNewBook({ title: 'Vue入門', author: '伊藤花子', return: true });
addNewBook({ title: 'Python入門', author: '鈴木花子', return: true });

//本を借りるてすぐに返却
borrowedBooks('TypeScript入門');
returnBook('1');

//console.log(books);
//console.log(borrowedBooks);
```
(2)TypeScriptに変更する

```index.ts
//本の在庫
const books = [
  { id: 1, title: 'TypeScript入門', author: '田中太郎', available: true },
  { id: 2, title: 'JavaScript入門', author: '山田太郎', available: false },
  { id: 3, title: 'React入門', author: '鈴木太郎', available: true },
];
//TypeでBook型を作成する
type Book = {
  id: number;
  title: string;
  author: string;
  available: boolean;
};

//ネストオブジェクトをTypeで宣言
type BorrowedBook = {
  id: number;
  book: Book;
  status: 'borrowed' | 'returned';
};

//借りた本をリストを保存
const borrowedBooks: BorrowedBook[] = [];
let newBookId = 1;

//本が入荷した時に書籍リストに追加
function addNewBook(book: Book) {
  books.push(book);
  return book;
}

//借りたい本のタイトルを関数に渡すと貸してくれる
function borrowedBook(title: string) {
  const selectedBook = books.find(
    (book) => book.title == title && book.available
  );
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('貸し出しする本が見つかりませんでした');
    return;
  }

  selectedBook.available = false;
  const newBorrowedBook: BorrowedBook = {
    id: newBookId++,
    book: selectedBook,
    status: 'borrowed',
  };
  borrowedBooks.push(newBorrowedBook);
  return selectedBook;
}

//借りた本の返却
function returnBook(bookId: number) {
  const selectedBook = borrowedBooks.find((book) => book.id === bookId);
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('返却する本が見つかりませんでした');
    return;
  }

  selectedBook.book.available = true;
  selectedBook.status = 'returned';
  return selectedBook;
}
//本のタイトル及びIDを受け取ったらその本を返す
function getBookDetail(identifier: string | number) {
  if (typeof identifier === 'string') {
    return books.find((book) => book.title === identifier);
  } else {
    return books.find((book) => book.id === identifier);
  }
}

//新しい本の追加
addNewBook({ id: 4, title: 'Vue入門', author: '伊藤花子', available: true });
addNewBook({ id: 5, title: 'Python入門', author: '鈴木花子', available: true });

//本を借りるてすぐに返却
borrowedBook('TypeScript入門');
returnBook(1);

//console.log(books);
//console.log(borrowedBooks);
```
## 関数の型

①function.tsを作成する
```function.ts
import { Book } from './book';
//本のタイトル及びIDを受け取ったらその本を返す
export function getBookDetail(
  identifier: string | number,
  books: Book[]
): Book {
  const book =
    typeof identifier === 'number'
      ? books.find((book) => book.id === identifier)
      : books.find((book) => book.title === identifier);
  if (!book) {
    throw new Error('本が見つかりませんでした');
  }
  return book;
}
```
②book.tsを作成する

```book.ts
//TypeでBook型を作成する
export type Book = {
  id: number;
  title: string;
  author: string;
  available: boolean;
};
```

③index.tsを編集する

```index.ts
import { getBookDetail } from './function';
import { Book } from './book';

//本の在庫
const books = [
  { id: 1, title: 'TypeScript入門', author: '田中太郎', available: true },
  { id: 2, title: 'JavaScript入門', author: '山田太郎', available: false },
  { id: 3, title: 'React入門', author: '鈴木太郎', available: true },
];

//ネストオブジェクトをTypeで宣言
type BorrowedBook = {
  id: number;
  book: Book;
  status: 'borrowed' | 'returned';
};

//借りた本をリストを保存
const borrowedBooks: BorrowedBook[] = [];
let newBookId = 1;

//本が入荷した時に書籍リストに追加
function addNewBook(book: Book): void {
  books.push(book);
}

//借りたい本のタイトルを関数に渡すと貸してくれる
function borrowedBook(title: string) {
  const selectedBook = books.find(
    (book) => book.title == title && book.available
  );
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('貸し出しする本が見つかりませんでした');
    return;
  }

  selectedBook.available = false;
  const newBorrowedBook: BorrowedBook = {
    id: newBookId++,
    book: selectedBook,
    status: 'borrowed',
  };
  borrowedBooks.push(newBorrowedBook);
  return selectedBook;
}

//借りた本の返却
function returnBook(bookId: number) {
  const selectedBook = borrowedBooks.find((book) => book.id === bookId);
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('返却する本が見つかりませんでした');
    return;
  }

  selectedBook.book.available = true;
  selectedBook.status = 'returned';
  return selectedBook;
}

//新しい本の追加
addNewBook({ id: 4, title: 'Vue入門', author: '伊藤花子', available: true });
addNewBook({ id: 5, title: 'Python入門', author: '鈴木花子', available: true });

//本を借りるてすぐに返却
borrowedBook('TypeScript入門');
returnBook(1);
getBookDetail('TypeScript入門', books);

console.log(books);
console.log(borrowedBooks);
```

## ユーティリティ型 Omit <T, Keys>
①idを無くす

```index.ts
import { getBookDetail } from './function';
import { Book } from './book';

//本の在庫
const books = [
  { id: 1, title: 'TypeScript入門', author: '田中太郎', available: true },
  { id: 2, title: 'JavaScript入門', author: '山田太郎', available: false },
  { id: 3, title: 'React入門', author: '鈴木太郎', available: true },
];

//ネストオブジェクトをTypeで宣言
type BorrowedBook = {
  id: number;
  book: Book;
  status: 'borrowed' | 'returned';
};

//借りた本をリストを保存
const borrowedBooks: BorrowedBook[] = [];
let newBookId = 1;

//本が入荷した時に書籍リストに追加　　　Omit <T, Keys>を使う
function addNewBook(book: Omit<Book, 'id'>): void {
  const newBook = {
    id: newBookId++,
    ...book,
  };
  books.push(newBook);
}

//借りたい本のタイトルを関数に渡すと貸してくれる
function borrowedBook(title: string) {
  const selectedBook = books.find(
    (book) => book.title == title && book.available
  );
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('貸し出しする本が見つかりませんでした');
    return;
  }

  selectedBook.available = false;
  const newBorrowedBook: BorrowedBook = {
    id: newBookId++,
    book: selectedBook,
    status: 'borrowed',
  };
  borrowedBooks.push(newBorrowedBook);
  return selectedBook;
}

//借りた本の返却
function returnBook(bookId: number) {
  const selectedBook = borrowedBooks.find((book) => book.id === bookId);
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('返却する本が見つかりませんでした');
    return;
  }

  selectedBook.book.available = true;
  selectedBook.status = 'returned';
  return selectedBook;
}

//新しい本の追加
addNewBook({ title: 'Vue入門', author: '伊藤花子', available: true });
addNewBook({ title: 'Python入門', author: '鈴木花子', available: true });

//本を借りるてすぐに返却
borrowedBook('TypeScript入門');
returnBook(1);
getBookDetail('TypeScript入門', books);

console.log(books);
console.log(borrowedBooks);
```
## ジェネリクス型

```index.ts
import { getBookDetail } from './function';
import { Book } from './book';

//本の在庫
const books = [
  { id: 1, title: 'TypeScript入門', author: '田中太郎', available: true },
  { id: 2, title: 'JavaScript入門', author: '山田太郎', available: false },
  { id: 3, title: 'React入門', author: '鈴木太郎', available: true },
];

//ネストオブジェクトをTypeで宣言
type BorrowedBook = {
  id: number;
  book: Book;
  status: 'borrowed' | 'returned';
};

//借りた本をリストを保存
const borrowedBooks: BorrowedBook[] = [];
let newBookId = 1;

//本が入荷した時に書籍リストに追加 ジェネリクス型
function addArray<T>(array: T[], item: T) {
  array.push(item);
  return array;
}

//借りたい本のタイトルを関数に渡すと貸してくれる
function borrowedBook(title: string) {
  const selectedBook = books.find(
    (book) => book.title == title && book.available
  );
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('貸し出しする本が見つかりませんでした');
    return;
  }

  selectedBook.available = false;
  const newBorrowedBook: BorrowedBook = {
    id: newBookId++,
    book: selectedBook,
    status: 'borrowed',
  };
  borrowedBooks.push(newBorrowedBook);
  return selectedBook;
}

//借りた本の返却
function returnBook(bookId: number) {
  const selectedBook = borrowedBooks.find((book) => book.id === bookId);
  //タイプガードを入れる
  if (!selectedBook) {
    console.error('返却する本が見つかりませんでした');
    return;
  }

  selectedBook.book.available = true;
  selectedBook.status = 'returned';
  return selectedBook;
}

//新しい本の追加
addArray<Book>(books, {
  id: newBookId++,
  title: 'Python入門',
  author: '鈴木花子',
  available: true,
});

//本を借りるてすぐに返却
borrowedBook('TypeScript入門');
returnBook(1);
getBookDetail('TypeScript入門', books);

console.log(books);
console.log(borrowedBooks);
```


## 参考サイト
[Learn TypeScript - Full Course for Beginners](https://www.youtube.com/watch?v=SpwzRDUQ1GI)
[【完全版】1時間でTypeScriptの基本、すべてマスターできます！](https://www.youtube.com/watch?v=ZDs1ddN2ag0&list=WL&index=3&t=1414s)