Czas polaczyc cała wiedze z tego modułu w jeden projekt! Zbudujesz typowany dashboard kosmiczny, który wykorzystuje:
Dashboard kosmiczny sklada sie z kilku sekcji:
1// Bazowy interfejs
2interface SpaceEntity {
3 id: string;
4 name: string;
5 discoveredYear: number;
6}
7
8// Discriminated union - różne typy obiektów
9interface PlanetEntity extends SpaceEntity {
10 kind: "planet";
11 radius: number;
12 habitable: boolean;
13}
14
15interface StarEntity extends SpaceEntity {
16 kind: "star";
17 temperature: number;
18 spectralClass: "O" | "B" | "A" | "F" | "G" | "K" | "M";
19}
20
21interface AsteroidEntity extends SpaceEntity {
22 kind: "asteroid";
23 diameter: number;
24 composition: string;
25}
26
27type CosmicObject = PlanetEntity | StarEntity | AsteroidEntity;
28
29// Stan dashboardu
30interface DashboardState {
31 objects: CosmicObject[];
32 filter: CosmicObject["kind"] | "all";
33 searchQuery: string;
34}1// Generyczny komponent tabeli z pelnym typowaniem
2interface Column<T> {
3 key: keyof T;
4 label: string;
5 render?: (value: T[keyof T], item: T) => React.ReactNode;
6}
7
8interface DataTableProps<T extends { id: string }> {
9 data: T[];
10 columns: Column<T>[];
11 onRowClick?: (item: T) => void;
12}
13
14function DataTable<T extends { id: string }>({
15 data, columns, onRowClick
16}: DataTableProps<T>) {
17 return (
18 <table>
19 <thead>
20 <tr>
21 {columns.map(col => (
22 <th key={String(col.key)}>{col.label}</th>
23 ))}
24 </tr>
25 </thead>
26 <tbody>
27 {data.map(item => (
28 <tr key={item.id} onClick={() => onRowClick?.(item)}>
29 {columns.map(col => (
30 <td key={String(col.key)}>
31 {col.render
32 ? col.render(item[col.key], item)
33 : String(item[col.key])}
34 </td>
35 ))}
36 </tr>
37 ))}
38 </tbody>
39 </table>
40 );
41}1type NewObjectForm =
2 | { kind: "planet"; name: string; radius: string; habitable: boolean }
3 | { kind: "star"; name: string; temperature: string; spectralClass: string }
4 | { kind: "asteroid"; name: string; diameter: string; composition: string };
5
6function AddObjectForm({ onAdd }: { onAdd: (obj: CosmicObject) => void }) {
7 const [kind, setKind] = useState<CosmicObject["kind"]>("planet");
8 const [name, setName] = useState("");
9
10 const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
11 e.preventDefault();
12 // Tworzy odpowiedni obiekt na podstawie wybranego typu
13 const id = crypto.randomUUID();
14 const year = new Date().getFullYear();
15
16 // ... logika tworzenia obiektu
17 };
18
19 return (
20 <form onSubmit={handleSubmit}>
21 <select
22 value={kind}
23 onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
24 setKind(e.target.value as CosmicObject["kind"])
25 }
26 >
27 <option value="planet">Planeta</option>
28 <option value="star">Gwiazda</option>
29 <option value="asteroid">Asteroida</option>
30 </select>
31 <input value={name} onChange={e => setName(e.target.value)} />
32 <button type="submit">Dodaj</button>
33 </form>
34 );
35}Poniżej znajdziesz kompletna implementacje dashboardu kosmicznego z pelnym typowaniem TypeScript. Przeanalizuj kod, zmodyfikuj go i eksperymentuj z typami!