前提
筆者はJSで計算機を開発した経験があります。
仕事上TSを学ぶ必要が出てきたので早足で学習を進めます。
筆者が効率的に思い出せる書き方にしています。
次の記事に続きます。
基礎知識
TypeScript
エラー検閲官。
コンパイル時にJSファイルを出力。
JavaScript XML(DOM APIの一種)を用いてwebの動的編集をする。
React
UIの状態管理に優れるパッケージ (標準からのズレのこと)
仮想DOM 宣言的UI
return <p>Hello</p>
Node.js
OS資源の操作のAPIを提供
命名由来:単一スレッドで"非同期にFIFO形式で非同期処理を裁く仕組み
npm: 派生モジュール管理ツール yarnよりnpxを使おう
コンパイラとしてテスト環境に導入必須
Next.js
SSRという技術で作成済みのhtmlファイルを送る (fetch APIを使用)
バンドラーの編集の手間が省ける
Reactとの互換性がつよい(通称front engineのframework)
1 fileにつき1 page componentを作成
fetch API 一覧
getServerSideProps: ページがリクエストされるたびにページのプロパティを返す
getStaticProps: ビルド時に実行され静的生成するページのデータを取得する
getInitialProps: SSR時にサーバーサイドでデータ取得の処理を実行する
CSS モジュール
import stylename from "./rootname.module.css";
と読み込んで、クラスごとにclassName = {stylename.button}
など指定できるので衝突しなくなる。
Vercel
TS文法
外部ファイルとの連携
export default funcname;
import funcname from "./filename";
自閉タグ + returnルール
function FunctFirst
return (
<>
<funcname />
<funcname />
</>
);
状態更新関数:constを変更可能 代わりにUIの更新を伴う
const [count, setCount] = useState(999);
const handleClick = () => {
setCount(count + 1);
};
return (
<span className="likeButton" onClick={handleClick}>
Count: {count}
</span>
);
//豆知識:BatchingとVirtual DOM Diffingの技術で再renderingは最小限に抑えられている
他のHook APIの例
useEffect //副作用(fetchやconsole.logなど)を扱う
useRef //DOMアクセスや前回の値の保持
useContext //グローバル状態の共有
useReducer //複雑な状態管理
条件付きrendering
{show && <funcname />} //再mountingが発生し関数の状態が初期化される
{loading || <img src={imageUrl} />} //falseの時のみに画像を表示
Promiseを攻略
//非同期処理の状態を簡単取得できるのだ(Pending/Fulfilled/Rejected)
doSomething()
.then(() => {
// 非同期処理(resolveを待つ)
})
.catch(() => {
// 非同期処理(rejectを待つ)
})
.finally(() => {
// 非同期処理(then、またはcatchを待つ)
});
カスタム型注釈 + 型ガード攻略 + APIにリクエストする
type Image = {
url = string;
};
// 飽くまで型ガードは戻り値の披露にすぎない
// 変数に付けるカスタム型注釈と違い、実際にコンパイラが評価するわけではない
const fetchImage = async (): Promise<Image> => {
const res = await fetch("https://api.dne.com/ksm");
// unknownは何にでも対応するので、不確定情報を拾う時にts使用者には必須
const images: unknown = await res.json();
if (!Array.isArray(images)) throw new Error("F");
const image: unknown = images[0];
if (!isImage(image)) throw new Error("F");
return image;
};
// Return true if
// 1) value is not null, and
// 2) value's datatype is within object, and
// 3) value.url exists, and
// 4) value.url's datatype is string
const isImage = (value: unknown): value is Image => {
if (!value || typeof value !== "object") return false;
return "url" in value && typeof value.url === "string";
};
補足
Bashで半自動化 tsファイル翻訳 → js実行をrun.bashで完結
#!/bin/bash
tsc "$1.ts"
if [ -f "$1.js" ]; then
node "$1.js"
else
echo "Error: $1.js not found. Compilation may have failed."
fi
ビルドのコマンド
npm run dev
ルート構造
project-root
//ここを弄る
pages //この下にあるファイル名がそのままurlに適用される 詳細は別記
//アレンジ可
tsconfig.json //コンパイラ設定する 自動生成される
.gitignore //軽量化のために.nextとnode_modulesをバージョン管理から外すべき
//基本触らない
.next //next build時に生成される この中身を本番環境で使う
node_modules //npmで自動生成されるバンドラー達
next-endv.d.ts //next.jsをjavascriptたらしめるもの
package.json //バンドラー内の依存関係を管理する
package-lock.json //依存関係を固定する
urlを課すルール pagesディレクトリ下
//1) tsxファイル(TypeScript用のJSX)にurlのroot名を充てる
//index.tsx ←空白
//name.tsx ←name
//[param].tsx ←param
//2) NextPageというインターフェイス的なのでコンパイラに明示する
import { NextPage } from "next";
const GreetingPage: NextPage = () => { //アロー関数という 宣言とは異なる
return <div><h1>わーっは!</h1></div>;
};
export default GreetingPage;
fiber treeの例 memoized処理(メモ)で再計算を防止
FiberRoot (App Root)
│
├── App (FunctionComponent)
│ ├── Header (FunctionComponent)
│ │ └── Logo (FunctionComponent)
│ ├── Main (FunctionComponent)
│ │ ├── Article (FunctionComponent)
│ │ │ └── Paragraph (FunctionComponent)
│ │ └── Sidebar (FunctionComponent)
│ │ └── UserProfile (FunctionComponent)
│ └── Footer (FunctionComponent)
│ └── Copyright (FunctionComponent)