TypeScriptを学んでいく
動機
サーバーサイドメインだけどフロントも理解していいプロダクトを作れるようにしたいので、TypeScriptを学びつつJavaScriptの復習などしていく。
同じような人や勉強したことを忘れたころの自分に向けて勉強の手順や参考にした資料などを残していく。
これまでやったこと
-
サバイバルTypeScript
素晴らしい資料なので初めてTypeScriptを学ぶ人にはぜひ参考にしてほしい
普段サーバーサイド系の言語ばかり触っているのもあってJavaScriptのよくわかっていなかった部分も学べとても参考になった
感謝です
「手を動かしながら学ぶTypeScript」をやる
現在CHAPTER03まで終わりメモも増えてきたので順次学んだことを備忘録として残していく。
CHAPTER03
commandで動くアプリケーションの構築
Docker環境の構築
Docker環境で実行したかったのでDockerfile, docker-compose.ymlを用意して実行。
Dockerfile
FROM node:20
RUN apt-get update && apt-get install -y vim
# timezone setting
ENV TZ='Asia/Tokyo'
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /root
COPY . .
# Set Up
RUN npm install yarn && npm install typescript -g && yarn init -y
RUN yarn install
docker-compose.yml
version: "3"
services:
node-app:
build:
context: ./node-app/
volumes:
- ./node-app:/root
tty: true
stdin_open: true
まとめ
- interfaceと型エイリアス
扱い方は多少違うがどちらを使っても同じオブジェクトを表現できる
プロジェクトで統一されていればどちらを使ってもいい
違い- 型合併の方法に違いがある
- interfaceはdecriation mergingという、同じ名前で定義されたインターフェースはその内容がマージされるという機能がある
- 型アサーションとほかの言語のキャストの違い
型キャストはランタイムで変換をするが、TypeScriptの型アサーションはあくまでコンパイル時に行うので、ランタイムの挙動に変化はない
型アサーションはTypeScriptの担っている責務を開発者側で負う処理なので、バグが混入しないようにしっかり考える - ジェネリクス
TypeScriptのジェネリクスは型を動的に扱うための機能 - literal type widening:ミュータブルな値の型は自動的に汎用的に変換される
const personName = '田中太郎' // '田中太郎'型 const person = { name: personName, // オブジェクトに代入されるとstring型になる } type PersonName = typof person // { name: string } 型
as const
を使うことでオブジェクトでも型を引き継げるconst personName = '田中太郎' // '田中太郎'型 const person = { name: personName, // '田中太郎'型 } as const type PersonName = typof person // { name: '田中太郎' } 型
- インデックスシグネチャ: 何かしらのstringがキーとなるオブジェクトを定義する方法
- 抽象クラス
abstruct
がついたクラスで、インスタンス化などはせず、複数のクラスの共通の形式を定義するときに使う
抽象クラスを利用してクラスを作るときはimplements
というキーワードを使う - TypeScriptでは宣言した変数の「型情報」はグローバルの名前空間に登録されるため、ファイルをまたいでも参照できる
CHAPTER04
Node.jsをつかったアプリケーションの構築
モジュールの歴史
- CommonJS
- サーバーサイドのようなWebブラウザ環境以外のJavaScriptの仕様を定めるためのプロジェクト(またはその仕様自体)
もともとNode.jsでモジュール実装され、その後CommonJSの仕様が作られていったためNode.jsはしっかりこれに従っているわけではない - ECMAScript Modules(ESModules)
2015年にECMAScriptの正式なモジュールシステムの仕様が定まり、乱立していたモジュールの記述方法がこれに統一されていった
統一はされたものの、ブラウザがそれを採用しないことにはその仕様で記述することができなかった
- サーバーサイドのようなWebブラウザ環境以外のJavaScriptの仕様を定めるためのプロジェクト(またはその仕様自体)
- webpack
モジュールの依存性解決ツール(モジュールバンドラー)で、複数のモジュールの依存関係を解決して1つのファイルにまとめてくれる- webpackがやってくれることの例
JavaScript単体ではできないことを叶えてくれる- loader機能でTypeScriptのファイルをJavaScriptに変換し、依存性を解決
- 画像やCSSをJavaScript上で使用できるようにする
- コード最適化によるファイルサイズの削減
- 環境変数の埋め込み
-
webpack.config.js
のmodule.exports
に渡される内容がwebpackの設定 - Node.jsで実行されるのでCommonJS形式で書く
- webpackによって変換された後のコードと元のコードを関連付けるのがソースマップ
これがあることで、ブラウザのデバッガーからもともとの記述を参照できる
- webpackがやってくれることの例
実装
-
npm
--save-dev
- 開発に必要なパッケージとしてインストール
-
npm run build
したらerror:0308010C:digital envelope routines::unsupported
npm: 10.1.0
node: 20.9.0
dockerでnode:20のイメージを使っている。package.json
"scripts": { - "build": "webpack" + "build": "NODE_OPTIONS='--openssl-legacy-provider' webpack" }
下記を参考にNODE_OPTIONSをしていしてOpenSSLをレガシーのものに戻すことで通った
本自体も少し古いのでそのせいもあるかも
.d.ts
型定義ファイル
これがあることによって npm install
でJavaScriptで記載されたライブラリを読み込んでもTypeScriptで扱うことができる
ただ、型定義ファイルのないライブラリはTypeScriptで取り扱うことができない…
そんな時は、多くの場合DefinitelyTypedというリポジトリから型定義ファイルをインストールできる
npm install @types/パッケージ名
※ライブラリの作成者と型定義ファイルの作成者は別なので間違っていることもある
どうしてもない場合は自分で作るということもできる
CHAPTER05
React.jsをつかったWEBアプリケーションの構築
Reactのお作法が分かってないのでちょっと難しかったが完走
メモ
-
stypled-components
- コンポーネントのスタイルを設定するもの
-
Utility Types
- 既存の型に対して、特定のプロパティをオプショナルにしたり、必須にしたり、Readonlyにしたりすることができる
毎日ちょこちょこ進めて1か月ちょっとかかったが、実際手を動かして進める方法だから身に付きやすかった。
説明もわかりやすいので同じような初学者におすすめ。