TypeScript dengan Vue — Vue

Vue 3 memiliki dukungan TypeScript yang sangat baik, terutama dengan . Props dengan TypeScript: interface Props { nama: string umur: number isAdmin?: boolean…

TypeScript di Vue berarti menulis <script setup lang="ts"> dan menyebut bentuk props, emits, dan ref sebagai tipe. Alat bernama vue-tsc lalu memeriksa script dan template sebelum aplikasinya dijalankan. Bayangin formulir pesanan di Warung Bu Sri yang kolomnya berlabel: "nama menu (teks)", "harga (angka)". Kasir memeriksa formulir di meja depan. Pesanan yang menulis "lima belas ribu" di kolom angka ditolak di meja itu, bukan baru ketahuan waktu piringnya sudah sampai di meja pembeli. vue-tsc itu kasirnya, dan browser itu dapurnya.

🧪 Tebakan cepat: MenuCard menyatakan harga: number, lalu App.vue menulis <MenuCard nama="Nasi Goreng" harga="15000" />, tanpa titik dua. Siapa yang protes duluan: vue-tsc saat type-check, atau browser saat halamannya dibuka? Tebak dulu, jawabannya ada di bagian "Yang ditangkap vue-tsc".

lang="ts" dan defineProps berbasis tipe

<!-- src/components/MenuCard.vue -->
<script setup lang="ts">
const props = defineProps<{
  nama: string
  harga: number
  stok?: number
}>()

const emit = defineEmits<{
  tambah: [nama: string, harga: number]
}>()

function klikTambah() {
  emit("tambah", props.nama, props.harga)
}
</script>
props: {
  nama: { type: String, required: true },
  harga: { type: Number, required: true },
  stok: { type: Number, required: false }
},
emits: ["tambah"],

Jadi build development tetap memeriksa props saat aplikasinya jalan, seperti di pelajaran props.

Nilai default dan emit bertipe

const props = withDefaults(
  defineProps<{ nama: string; harga: number; stok?: number }>(),
  { stok: 0 },
)

ref bertipe

const jumlah = ref(0)                        // Ref<number>, ditebak dari 0
const terakhir = ref<number | null>(null)    // angka, atau null sebelum ada pesanan
const keranjang = ref<{ nama: string; harga: number }[]>([])
const total = computed(() => keranjang.value.reduce((a, i) => a + i.harga, 0)) // ComputedRef<number>

Yang ditangkap vue-tsc

Proyek TypeScript dari create-vue punya script type-check yang menjalankan vue-tsc --build. Ini keluaran sungguhannya untuk harga="15000" (tipe panjang di baris terakhir dipotong di sini):

$ npm run type-check

> [email protected] type-check
> vue-tsc --build

src/App.vue:16:32 - error TS2322: Type 'string' is not assignable to type 'number'.

16   <MenuCard nama="Nasi Goreng" harga="15000" :stok="8" @tambah="tambahKeKeranjang" />
                                  ~~~~~

  src/components/MenuCard.vue:4:3
    4   harga: number
        ~~~~~
    The expected type comes from property 'harga' which is declared here on type '{ readonly nama: string; ... }'

Found 1 error.

vue-tsc yang protes duluan, sebelum halamannya pernah dibuka. Itu jawaban tebakannya. Kesalahan lain yang ditangkapnya:

Kesalahan Pesan vue-tsc
<MenuCard :harga="15000" /> tanpa nama error TS2345: ... diikuti Property 'nama' is missing in type '{ harga: number; ... }'
emit("tambah", props.harga, props.nama) error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
emit("tamba", props.nama, props.harga) error TS2345: Argument of type '"tamba"' is not assignable to parameter of type '"tambah"'.
const terakhir = ref(null) lalu terakhir.value = harga error TS2322: Type 'number' is not assignable to type 'null'.

Di editor latihan

Latihannya berisi dua file .vue di satu editor, masing-masing dimulai baris <!-- NamaFile.vue -->: ProfileCard.vue dan App.vue. Editor menerjemahkannya dengan compiler Vue yang sama dengan Vite (@vue/compiler-sfc), jadi <script setup lang="ts"> dan defineProps<...>() jalan seperti di proyek sungguhan:

<!-- ProfileCard.vue -->
<script setup lang="ts">
defineProps<{
  nama: string
  umur: number
}>()
</script>

<template>
  <div>
    <h2 id="name">{{ nama }}</h2>
    <p id="age">{{ umur }} tahun</p>
  </div>
</template>

⚠️ Jebakan yang sering ketemu

TL;DR: <script setup lang="ts"> menyalakan TypeScript di file .vue. Props dinyatakan lewat tipe dengan defineProps<{ nama: string; harga: number; stok?: number }>(), default lewat withDefaults atau stok = 0 saat membongkar (Vue 3.5+), dan event lewat defineEmits<{ tambah: [nama: string, harga: number] }>(). Compiler mengubah tipe itu jadi deklarasi props runtime. ref(0) ditebak sendiri, tapi ref(null) perlu ref<number | null>(null). vue-tsc (lewat npm run type-check) menangkap prop yang salah tipe, prop wajib yang hilang, dan emit yang salah nama atau urutan, sebelum browser menjalankan apa pun; npm run dev gak memeriksa tipe. Editor latihan menerjemahkan <script setup lang="ts"> seperti Vite: tipe jadi props, lalu dihapus tanpa diperiksa.

Yang akan kamu pelajari