Analisis statis

Analisis statis adalah jenis pengujian yang menyediakan pemeriksaan otomatis terhadap kode tertentu tanpa benar-benar menjalankannya atau harus menulis pengujian otomatis. Anda sudah sepertinya sudah melihat pengujian semacam ini jika Anda menggunakan IDE seperti VSCode—jenis pemeriksaan yang dilakukan oleh TypeScript adalah semacam analisis statis, dan dapat menampilkan sebagai garis berlekuk-lekuk di bawah kesalahan atau peringatan.

ESLint adalah alat yang dapat memberikan masukan{i> <i}tentang kemungkinan masalah dalam saat ini. Masalah ini mungkin jenisaman,tetapi error atau perilaku non-standar secara mandiri. ESLint memungkinkan Anda menerapkan sejumlah aturan yang diperiksa codebase Anda, termasuk banyak dalam kolom "direkomendasikan" atur.

Contoh yang baik dari aturan ESLint adalah no-unsafe-finally aturan. Hal ini mencegah Anda menulis pernyataan yang memodifikasi alur kontrol di dalam blok finally. Ini adalah aturan yang baik, karena melakukan hal ini adalah cara yang tidak biasa untuk menulis JavaScript yang sulit diikuti. Namun, sesuatu yang harus dapat dideteksi oleh proses peninjauan kode yang sehat.

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

Dengan demikian, ESLint bukanlah pengganti proses peninjauan yang sehat (dan gaya yang menentukan tampilan codebase Anda), karena ini tidak akan untuk menangkap setiap pendekatan ortodoks yang mungkin coba diperkenalkan oleh pengembang ke dalam codebase Anda. Panduan Praktik Bahasa Inggris Google memiliki bagian singkat tentang "kemudahan".

ESLint memungkinkan Anda melanggar aturan dan memberi anotasi pada kode sebagai "diizinkan". Sebagai contoh, Anda dapat mengizinkan logika sebelumnya dengan menganotasinya sebagai berikut:

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

Jika Anda terus-menerus melanggar aturan, pertimbangkan untuk menonaktifkannya. Ini alat mendorong Anda untuk menulis kode dengan cara tertentu, tetapi tim Anda mungkin digunakan menulis kode dengan cara yang berbeda dan sudah menyadari risikonya pendekatan.

Terakhir, mengaktifkan alat analisis statis pada codebase besar mungkin akan menghasilkan banyak derau yang tidak membantu (dan pekerjaan sibuk untuk memfaktorkan ulang) pada kode yang berfungsi baik. Jadi, lebih mudah untuk mengaktifkannya di awal siklus proses project.

Plugin ESLint untuk dukungan browser

Anda dapat menambahkan plugin ke ESLint yang menandai penggunaan API yang tidak didukung, atau tidak didukung oleh daftar browser target Anda. Tujuan eslint-plugin-compat bisa memperingatkan Anda bila API mungkin tidak tersedia untuk pengguna, jadi Anda tidak perlu terus-menerus melacak diri sendiri.

Pemeriksaan jenis untuk analisis statis

Saat mempelajari JavaScript, developer baru biasanya diperkenalkan dengan ide tersebut bahwa ini adalah bahasa yang diketik dengan lemah. Yaitu, dimungkinkan untuk mendeklarasikan variabel sebagai satu jenis, lalu gunakan lokasi yang sama untuk sesuatu yang berbeda. Ini mirip dengan Python dan bahasa {i>scripting<i} lainnya, tetapi tidak seperti bahasa yang dikompilasi seperti C/C++ dan Rust.

Bahasa semacam ini mungkin bagus untuk memulai—dan bisa dibilang ini kesederhanaan yang membuat JavaScript begitu populer—tetapi sering kali merupakan titik kegagalan untuk beberapa codebase, atau setidaknya sesuatu yang terjadi. Misalnya, dengan meneruskan number dengan string atau jenis objek nilai yang salah diketik dapat menyebar ke berbagai library sebelum akhirnya menyebabkan TypeError yang membingungkan.

TypeScript

TypeScript adalah solusi paling umum untuk JavaScript yang tidak memiliki pengetikan tidak akurat atau tidak sesuai. Kursus ini menggunakannya secara ekstensif. Dan meskipun ini bukan materi tentang TypeScript, ini dapat menjadi bagian penting dari {i>toolbox<i} Anda karena menyediakan analisis statis.

Untuk contoh singkat, kode ini, yang mengharapkan untuk diberi callback yang menerima Nama string dan usia number:

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

Menghasilkan error berikut saat dijalankan melalui TypeScript, atau bahkan ketika kursor diarahkan di IDE:

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
Kode dari model
  pada contoh sebelumnya, yang ditampilkan dalam IDE dengan pesan error
  di jendela pop-up.
VSCode yang menunjukkan bahwa Anda telah meneruskan respons yang salah jenis ini.

Pada akhirnya, tujuan menggunakan TypeScript adalah untuk mencegah error seperti ini— usia harus number, bukan string—yang menjalar ke dalam project Anda. Ini jenis kesalahan sulit dideteksi dengan jenis pengujian lainnya. Selain itu, sistem jenis dapat memberikan masukan sebelum pengujian ditulis. Ini dapat mempermudah proses penulisan kode dengan memberi Anda masukan awal tentang kesalahan jenis saat Anda mengembangkan perangkat lunak, bukan ketika kode akhirnya berjalan.

Bagian yang paling menantang dalam menggunakan TypeScript adalah menyiapkannya dengan benar. Setiap project memerlukan file tsconfig.json, yang terutama digunakan oleh tsc baris perintah itu sendiri, juga dibaca oleh IDE seperti VSCode dan alat dan alat build, termasuk Vitest. File ini berisi ratusan dan flag. Anda juga bisa menemukan beberapa referensi yang bagus untuk menyiapkannya di sini:

Tips umum TypeScript

Saat menyiapkan dan menggunakan TypeScript melalui file tsconfig.json, pertahankan berikut ini:

  • Pastikan file sumber Anda benar-benar disertakan dan dicentang. Jika file secara misterius "tidak memiliki kesalahan", kemungkinan karena tidak sedang diperiksa.
  • Menjelaskan jenis dan antarmuka secara eksplisit di dalam file .d.ts, bukan menjelaskannya secara implisit saat Anda menulis fungsi, bisa membuat lebih mudah untuk diuji. Lebih mudah untuk menulis tiruan dan 'palsu' versi dari kode ketika antarmuka yang terlibat sudah jelas. .

TypeScript implisit semua

Salah satu opsi konfigurasi TypeScript yang paling ampuh dan bermanfaat adalah noImplicitAny. Namun, sering kali ini juga yang paling sulit untuk diaktifkan, terutama jika Anda sudah memiliki codebase yang besar. (Tanda noImplicitAny adalah diaktifkan secara default jika Anda berada dalam mode strict, tetapi tidak sebaliknya.)

Flag ini akan membuat fungsi ini menampilkan error:

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Meskipun, sebagai pembaca, cukup jelas bahwa n harus berupa angka, TypeScript tidak dapat mengonfirmasi hal ini dengan yakin. Jika Anda menggunakan VSCode, arahkan kursor ke fungsi tersebut akan mendeskripsikannya sebagai berikut:

function fibonacci(n: any): any

Pemanggil fungsi ini akan dapat meneruskan nilai jenis any (jenis yang memungkinkan jenis lainnya), bukan hanya number. Dengan mengaktifkan noImplicitAny, Anda dapat mengamankan kode semacam ini selama pengembangan, tanpa perlu menulis pengujian logika bisnis yang ekstensif untuk penerusan kode tipe data yang salah di tempat tertentu.

Perbaikan sederhana di sini adalah dengan menandai argumen n dan jenis nilai yang ditampilkan fibonacci sebagai number.

Flag noImplicitAny tidak mencegah Anda secara eksplisit menulis any di codebase Anda. Anda masih dapat menulis fungsi yang menerima atau mengembalikan jenis any. Ini hanya memastikan bahwa Anda memberikan jenis untuk setiap variabel.