三重県の市町村の人口を調べるついでにTypeScriptを復習
地方自治法第8条では、市となる条件として以下の4つが挙げられている。
- 人口が5万人以上。ただし、市町村の合併の特例が適用されれば3万人以上でも可。
- 中心的市街地に全戸数の6割以上が存在すること。
- 商工業など都市的業態に従事する者とその同一世帯の人口が、全体の6割以上を占めること。
- 都道府県の条例で定められた都市的施設などの条件を満たすこと。
しかし実際には、市に昇格した当初は人口が5万人以上であっても、人口減少により現在は5万人未満となっている市もある。また、合併特例を使って5万人未満で市になった例も存在する。
そこで今回は、三重県の全市町村を対象に、「人口が5万人以上かどうか」という単純な基準で、現在の市の人口状況を調査してみる。その際、Vite+React+TypeScript+Tailwind CSSを使って、簡単な判定アプリを作成し、TypeScriptの基礎について復習もしてみたい。欲張り。
npm create vite@latest mie-city-checker -- --template react-ts
cd mie-city-checker
npm install
npm run dev
import React from "react";
type Municipality = {
name: string;
population: number;
};
const isCity = (municipality: Municipality): boolean => {
return municipality.population >= 50000;
};
// 出典:総務省統計局「統計でみる市区町村のすがた2024」
const municipalities: Municipality[] = [
{ name: "四日市市", population: 305424 },
{ name: "津市", population: 274537 },
{ name: "鈴鹿市", population: 195670 },
{ name: "松阪市", population: 159145 },
{ name: "桑名市", population: 138613 },
{ name: "伊勢市", population: 122765 },
{ name: "伊賀市", population: 88766 },
{ name: "名張市", population: 76387 },
{ name: "亀山市", population: 49835 },
{ name: "志摩市", population: 46057 },
{ name: "いなべ市", population: 44973 },
{ name: "三重郡菰野町", population: 40559 },
{ name: "員弁郡東員町", population: 25784 },
{ name: "多気郡明和町", population: 22445 },
{ name: "鳥羽市", population: 17525 },
{ name: "尾鷲市", population: 16252 },
{ name: "熊野市", population: 15965 },
{ name: "三重郡川越町", population: 15123 },
{ name: "度会郡玉城町", population: 15041 },
{ name: "北牟婁郡紀北町", population: 14604 },
{ name: "多気郡多気町", population: 14021 },
{ name: "三重郡朝日町", population: 11021 },
{ name: "度会郡南伊勢町", population: 10989 },
{ name: "南牟婁郡紀宝町", population: 10321 },
{ name: "多気郡大台町", population: 8668 },
{ name: "南牟婁郡御浜町", population: 8079 },
{ name: "度会郡度会町", population: 7847 },
{ name: "度会郡大紀町", population: 7815 },
{ name: "桑名郡木曽岬町", population: 6023 },
];
const App = () => {
return (
<div className="p-4 font-sans">
<h1 className="text-2xl font-bold mb-4">三重県 市町村判定アプリ</h1>
<ul className="space-y-2">
{municipalities.map((m) => (
<li key={m.name} className="p-2 border rounded shadow">
<div className="flex justify-between items-center">
<span>{m.name}</span>
<span>
{m.population.toLocaleString()}人{" "}
{isCity(m) && <span className="text-green-600 font-bold">✅</span>}
</span>
</div>
</li>
))}
</ul>
</div>
);
};
export default App;
この結果を見ると、亀山市、志摩市、いなべ市、鳥羽市、尾鷲市、熊野市は市であるにもかかわらず、人口が5万人を超えていない。また、人口が5万人以上いるのに町や村である市町村は存在しないこともわかる。
以下は、実装コードのTypeScriptについて。
まず、配列の型注釈について。
type MunicipalityはTypeScriptの型エイリアス(type alias)。市町村を次のような構造で定義している。
type Municipality = {
name: string; // 市町村名(例:"四日市市")
population: number; // 人口(例:305424)
};
これを元に、以下のようにして「三重県の市町村一覧」の配列の型を定義している。
const municipalities: Municipality[] = [ ... ];
このMunicipality[]は、「Municipality型のオブジェクトが複数入っている配列」という意味になる。
配列に型注釈する書き方にはType[]とArray<T>の2通りある。どちらも意味は同じ。
TypeScript入門書『サバイバルTypeScript』の著者であるsuinさんが行ったアンケートでは、Type[]を支持する声が多く、自分としてもこちらの方がシンプルで好きだ。
続いて、アロー関数の型注釈について。
const isCity = (municipality: Municipality): boolean => {
return municipality.population >= 50000;
};
これは「その市町村が、市の条件(今回は単純に人口5万人以上)を満たしているかどうか」を判定する関数。関数の引数にはMunicipality型を指定し、戻り値にはboolean型を明示している。
この関数をmapの中で使い、判定結果に応じて ✅ を表示している。
municipalities.map((m) => (
...
{isCity(m) && <span>✅</span>}
))
なお、JavaScriptのアロー関数は引数が1つの場合に括弧を省略できるが、TypeScriptでは括弧を省略すると型注釈が書けなくなる。型を明示したい場合は、括弧をつけておく方がよい。
参考資料:
Discussion