🧑‍⚕️

🩺【React × TypeScript × Tailwind CSS】医療系アプリの基準値判定システムを作る 全4回シリーズ

に公開

看護師 × エンジニアによる実装記録

医療アプリ開発で重要な「基準値(正常範囲)」判定機能。
React + TypeScript + Tailwind CSSで、
見やすく安全な“基準値UI”を設計していく過程を全4回でまとめました。


📚 シリーズ一覧

記事タイトル 内容概要
基準値より高い・低いを矢印で表示する方法 getStatusIconの実装・UI設計
normalRanges.tsで基準値を一元管理する設計パターン データ構造・型定義設計
型安全に基準値を比較するTypeScriptロジック unknown・型ガードによる安全比較
Tailwindで見やすい医療UIをデザインする 矢印UI・色設計・視認性改善

#1 基準値より高い・低いを矢印で表示する方法

💡 目的

React + TypeScript環境で、数値を基準値と比較し
「高値」「低値」を視覚的に矢印で表示する。

import { ArrowUp, ArrowDown } from "lucide-react";

export const getStatusIcon = (value: number, range?: { min: number; max: number }) => {
  if (!range) return null;
  if (value > range.max)
    return <ArrowUp className="w-4 h-4 text-red-500 ml-1" />;
  if (value < range.min)
    return <ArrowDown className="w-4 h-4 text-blue-500 ml-1" />;
  return null;
};

🧠 ポイント

  • lucide-reactアイコンで軽量かつTailwindで装飾可能
  • 値と基準値の比較はロジック層に分離
  • 数値の横にアイコンを配置し、瞬時に状態を把握可能

#2 normalRanges.tsで基準値を一元管理する設計パターン

💡 なぜ一元管理するのか

基準値を各コンポーネントに直接書くと、管理が分散し変更漏れが発生しやすい。
normalRanges.ts に統一管理することで、安全性・メンテ性を大幅に向上できます。


export const normalRanges = {
  sodium: { min: 135, max: 145 },
  potassium: { min: 3.5, max: 5.0 },
  bmi: { min: 18.5, max: 24.9 },
  temperature: { min: 36.0, max: 37.5 },
};

🧱 型定義(types/normalRange.ts)


export type Range = { min: number; max: number };
export type NormalRangeKeys = "sodium" | "potassium" | "bmi" | "temperature";
export type NormalRanges = Record<NormalRangeKeys, Range>;

✅ メリット

項目 内容
一貫性 全ページで同じ基準値を参照
メンテ性 修正は1箇所で完結
型安全 TypeScriptでmin/max構造を保証

#3 型安全に基準値を比較するTypeScriptロジック

⚙️ 安全な比較関数

export const compareValueToRange = (value: unknown, range?: Range) => {
  if (!range) return "none";

  const numericValue = parseFloat(String(value));
  if (isNaN(numericValue)) return "invalid";

  if (numericValue > range.max) return "high";
  if (numericValue < range.min) return "low";
  return "normal";
};

🧩 型ガードを追加するとさらに安全


export const isNumeric = (value: unknown): value is number => {
  return typeof value === "number" && !isNaN(value);
};

🧠 判定結果の型

type CompareResult = "high" | "low" | "normal" | "invalid" | "none";

✅ 安全化ポイント

項目 内容
unknownで受け取る 外部入力も安全に処理
parseFloatで統一変換 数値・文字列混在にも対応
型ガード 不正データを事前に排除

#4 Tailwindで見やすい医療UIをデザインする

💡 目的

比較結果を“医療アプリらしく、見やすく伝える”ためのUI設計。


<strong className="text-2xl flex items-center font-semibold leading-none tracking-wide">
  {value}
  {getStatusIcon(Number(value), range)}
</strong>

🧱 Tailwindクラス解説

クラス 効果
flex items-center 数値と矢印を横並び・中央揃え
leading-none 行間を詰めてすっきり表示
tracking-wide 数字の視認性アップ
text-red-400 / text-blue-400 彩度を抑えて目に優しい発色

🎨 カラー設計のポイント

状態 クラス 印象
高値 text-red-400 注意喚起だが柔らかい
低値 text-blue-400 冷静さ・清潔感
正常 text-gray-600 落ち着き・安定感

🚀 まとめ

学んだ内容
状態表示アイコン(高値↑・低値↓)の実装
normalRanges.tsで基準値を一元管理
型安全な比較ロジックの設計
Tailwindで医療UIをデザイン

🩺 本シリーズでは、**「UIの見やすさ × 型安全性 × 医療的信頼性」**を軸に、React + TypeScript + Tailwindを使った医療アプリ開発のベストプラクティスを実践しています。

Discussion