Closed6

TypeScriptを学んでいく

citron633citron633

動機

サーバーサイドメインだけどフロントも理解していいプロダクトを作れるようにしたいので、TypeScriptを学びつつJavaScriptの復習などしていく。
同じような人や勉強したことを忘れたころの自分に向けて勉強の手順や参考にした資料などを残していく。

これまでやったこと

  • サバイバルTypeScript
    素晴らしい資料なので初めてTypeScriptを学ぶ人にはぜひ参考にしてほしい
    普段サーバーサイド系の言語ばかり触っているのもあってJavaScriptのよくわかっていなかった部分も学べとても参考になった
    感謝です
citron633citron633

「手を動かしながら学ぶTypeScript」をやる

https://amzn.asia/d/3PMoEGT
何か実際に作りながら基礎を勉強していきたいと思い、こちらの本の勉強をはじめることにした。
現在CHAPTER03まで終わりメモも増えてきたので順次学んだことを備忘録として残していく。

citron633citron633

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では宣言した変数の「型情報」はグローバルの名前空間に登録されるため、ファイルをまたいでも参照できる
citron633citron633

CHAPTER04

Node.jsをつかったアプリケーションの構築

モジュールの歴史

  • CommonJS
    • サーバーサイドのようなWebブラウザ環境以外のJavaScriptの仕様を定めるためのプロジェクト(またはその仕様自体)
      もともとNode.jsでモジュール実装され、その後CommonJSの仕様が作られていったためNode.jsはしっかりこれに従っているわけではない
    • ECMAScript Modules(ESModules)
      2015年にECMAScriptの正式なモジュールシステムの仕様が定まり、乱立していたモジュールの記述方法がこれに統一されていった
      統一はされたものの、ブラウザがそれを採用しないことにはその仕様で記述することができなかった
  • webpack
    モジュールの依存性解決ツール(モジュールバンドラー)で、複数のモジュールの依存関係を解決して1つのファイルにまとめてくれる
    • webpackがやってくれることの例
      JavaScript単体ではできないことを叶えてくれる
      • loader機能でTypeScriptのファイルをJavaScriptに変換し、依存性を解決
      • 画像やCSSをJavaScript上で使用できるようにする
      • コード最適化によるファイルサイズの削減
      • 環境変数の埋め込み
    • webpack.config.jsmodule.exports に渡される内容がwebpackの設定
    • Node.jsで実行されるのでCommonJS形式で書く
    • 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/パッケージ名

※ライブラリの作成者と型定義ファイルの作成者は別なので間違っていることもある
どうしてもない場合は自分で作るということもできる

citron633citron633

CHAPTER05

React.jsをつかったWEBアプリケーションの構築
Reactのお作法が分かってないのでちょっと難しかったが完走

メモ

  • stypled-components

    • コンポーネントのスタイルを設定するもの
  • Utility Types

    Documentation - Utility Types

    • 既存の型に対して、特定のプロパティをオプショナルにしたり、必須にしたり、Readonlyにしたりすることができる
citron633citron633

毎日ちょこちょこ進めて1か月ちょっとかかったが、実際手を動かして進める方法だから身に付きやすかった。
説明もわかりやすいので同じような初学者におすすめ。

このスクラップは15日前にクローズされました