Project: Type-Safe Frontend App (Vite)
Introduction
This project builds a small Vite + TypeScript app that fetches typed API data and updates the DOM safely. You practice frontend tsconfig, import.meta.env, modeling API responses, and separating UI modules—without a heavy framework.
Prerequisites
Project Goals
- Load users from a public JSON API (or mock)
- Render a list with loading and error states
- Use discriminated union for UI state
- Type form input handling
Setup
bash
npm create vite@latest ts-users-app -- --template vanilla-ts
cd ts-users-app
npm installtext
src/
├── main.ts
├── api.ts
├── types.ts
├── ui.ts
└── style.cssAPI Types
src/types.ts:
typescript
export interface User {
id: number;
name: string;
email: string;
}
export type LoadState<T> =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: T }
| { status: "error"; message: string };Fetch Layer
src/api.ts:
typescript
.env:
text
VITE_API_URL=https://jsonplaceholder.typicode.comUI Module
src/ui.ts:
typescript
Main Entry
src/main.ts:
typescript
Run
bash
npm run dev
npm run buildnpm run build runs tsc then Vite—fix any type errors before shipping.
Extensions
- Add search input with typed debounce helper
- Migrate to React and move
LoadStateto a hook - Connect to your REST API from the API project chapter
FAQ
Why vanilla instead of React?
Focuses on types and DOM without JSX. React template is one command away.
CORS errors?
Use Vite server.proxy in vite.config.ts for local APIs.
Stricter env types?
Extend ImportMetaEnv in vite-env.d.ts.