Kurs Vue.js · Moduł 15: TypeScript i Nuxt

TypeScript z Vue.js

2 min czytania
W tej lekcji5

Witaj w Laboratorium Kwantowym NOVA LAB! Rok 2087 - systemy stacji kosmicznej wymagają najwyższej precyzji. Każdy błąd w typie danych może doprowadzić do katastrofy. Dlatego nasi inżynierowie używają TypeScript - statycznego systemu typów, który wykrywa błędy jeszcze zanim kod zostanie uruchomiony.

Dlaczego TypeScript z Vue?

TypeScript to nadzbiór JavaScriptu, który dodaje typy statyczne. W połączeniu z Vue 3 daje nam:

  • Autouzupełnianie w edytorze kodu (IntelliSense)
  • Wykrywanie błędów przed uruchomieniem aplikacji
  • Lepsza dokumentacja - typy opisują kształt danych
  • Refaktoryzacja - edytor rozumie strukturę kodu

Konfiguracja projektu Vue z TypeScript

Tworzenie projektu Vue z TypeScript jest proste dzięki Vite:

1npm create vite@latest nova-lab -- --template vue-ts

Vite automatycznie konfiguruje TypeScript i tworzy plik tsconfig.json:

1{
2  "compilerOptions": {
3    "target": "ES2020",
4    "module": "ESNext",
5    "moduleResolution": "bundler",
6    "strict": true,
7    "jsx": "preserve",
8    "paths": {
9      "@/*": ["./src/*"]
10    }
11  },
12  "include": ["src/**/*.ts", "src/**/*.vue"]
13}

Atrybut lang="ts"

W komponentach Vue SFC (Single File Components) dodajemy lang="ts" do bloku <script setup>:

1<script setup lang="ts">
2import { ref } from 'vue'
3
4const stationName = ref<string>('NOVA LAB')
5const crewCount = ref<number>(42)
6const isOnline = ref<boolean>(true)
7</script>

Bez lang="ts" Vue traktuje kod jako zwykły JavaScript. Z lang="ts" kompilator TypeScript sprawdza typy i wychwytuje błędy.

Podstawowe typy w Vue

1<script setup lang="ts">
2import { ref } from 'vue'
3
4// Proste typy
5const name: string = 'Mars Station'
6const year: number = 2087
7const active: boolean = true
8
9// Tablice
10const modules: string[] = ['Lab', 'Hangar', 'Bridge']
11const temperatures: number[] = [-63, -58, -71]
12
13// Ref z typem generycznym
14const status = ref<string>('operational')
15const energy = ref<number>(98.5)
16</script>

TypeScript automatycznie wnioskuje (infer) typy, więc nie zawsze trzeba je podawać jawnie:

1const count = ref(0)       // ref<number> - wnioskowane automatycznie
2const label = ref('test')  // ref<string> - wnioskowane automatycznie

Jawne typowanie jest przydatne, gdy typ nie może być wnioskowany:

1const data = ref<string | null>(null)  // może być string lub null

Interfejsy TypeScript

Interfejsy definiują kształt obiektów:

1interface CrewMember {
2  id: number
3  name: string
4  role: string
5  active: boolean
6}
7
8const engineer: CrewMember = {
9  id: 1,
10  name: 'Dr. Nova',
11  role: 'Chief Engineer',
12  active: true
13}
Kod do tej lekcji: App.vue
1<script setup lang="ts">
2import { ref } from 'vue'
3
4// Podstawowe typy
5const stationName = ref<string>('NOVA LAB')
6const crewCount = ref<number>(42)
7const isOnline = ref<boolean>(true)
8
9// Interfejs
10interface CrewMember {
11  id: number
12  name: string
13  role: string
14  active: boolean
15}
16
17// Tablica z typem
18const crew = ref<CrewMember[]>([
19  { id: 1, name: 'Dr. Nova', role: 'Commander', active: true },
20  { id: 2, name: 'Atlas', role: 'Navigator', active: true },
21  { id: 3, name: 'Echo', role: 'Engineer', active: false }
22])
23
24// Typ unii
25const status = ref<'online' | 'offline' | 'maintenance'>('online')
26
27function toggleStatus() {
28  const states: Array<'online' | 'offline' | 'maintenance'> = ['online', 'offline', 'maintenance']
29  const idx = states.indexOf(status.value)
30  status.value = states[(idx + 1) % states.length]
31}
32</script>
33
34<template>
35  <div class="nova-lab">
36    <h1>{{ stationName }}</h1>
37    <p>Crew: {{ crewCount }} | Status: <span :class="status">{{ status }}</span></p>
38    <button @click="toggleStatus" class="btn">Zmien status</button>
39
40    <h2>Zaloga</h2>
41    <div v-for="member in crew" :key="member.id" class="card">
42      <strong>{{ member.name }}</strong> - {{ member.role }}
43      <span :class="member.active ? 'active' : 'inactive'">
44        {{ member.active ? 'Aktywny' : 'Nieaktywny' }}
45      </span>
46    </div>
47  </div>
48</template>
49
50<style scoped>
51.nova-lab {
52  background: #0a0e27;
53  color: #00ff88;
54  min-height: 100vh;
55  padding: 20px;
56  font-family: monospace;
57}
58h1 { color: #00ff88; margin-bottom: 5px; }
59h2 { color: #00b4d8; margin-top: 20px; }
60.btn {
61  background: #00b4d8;
62  color: white;
63  border: none;
64  padding: 8px 16px;
65  border-radius: 8px;
66  cursor: pointer;
67  margin: 10px 0;
68}
69.card {
70  background: rgba(0, 180, 216, 0.1);
71  border: 1px solid #00b4d8;
72  padding: 12px 16px;
73  margin: 6px 0;
74  border-radius: 8px;
75  display: flex;
76  justify-content: space-between;
77  align-items: center;
78}
79.online { color: #00ff88; }
80.offline { color: #e74c3c; }
81.maintenance { color: #f39c12; }
82.active { color: #00ff88; font-size: 12px; }
83.inactive { color: #e74c3c; font-size: 12px; }
84</style>

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Jaką główną korzyść daje użycie TypeScript z Vue.js?

  2. 2. Jaki atrybut dodajemy do bloku <script setup>, aby włączyć TypeScript?

To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Edytor kodu

    Typuj ref jako string, number, boolean i stwórz interfejs dla obiektu załogi.

  • Klikanie w kolejności

    Ułóż kroki konfiguracji projektu Vue z TypeScript:

  • Edytor kodu

    Zdefiniuj interfejs ModuleProps i użyj defineProps z generycznym typem.

Przydatne artykuły