Typescript: Pemeriksa jenis kehilangan jenis untuk-dari

Dibuat pada 8 Nov 2016  ·  3Komentar  ·  Sumber: microsoft/TypeScript

TypeScript Version: 2.0.8

Kode

// test.ts
interface Type {
  type: number;
}

interface TypeExt extends Type {
  arr: Type[];
}

const guard = (arg: Type): arg is TypeExt => arg.type === 1;
const otherFunc = (arg1: Type, arg2: TypeExt): void => {};

export function y(arg: Type): void {
  if (guard(arg)) {
    for (const ITEM/* error is here */ of arg.arr) {
      if (otherFunc(ITEM, arg)) {
      }
    }
  }
}

Disusun dengan cmd: tsc --noImplicitAny test.ts

Perilaku yang diharapkan:
Tidak ada kesalahan

Perilaku sebenarnya:

test.ts(14,16): error TS7022: 'ITEM' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Bug Fixed

Komentar yang paling membantu

Ini adalah masalah analisis aliran kontrol. Untuk menyimpulkan tipe untuk ITEM kita perlu mencari tipe aliran kendali dari arg.arr . Itu berarti kita perlu melihat konstruksi yang mempengaruhi tipe arg . Ini termasuk panggilan ke otherFunc yang sepertinya _bisa_ menjadi predikat tipe yang ditentukan pengguna. Untuk menentukan apakah itu _is_ predikat tipe, kita menyelesaikan ekspresi panggilan, yang memerlukan penyelesaian ekspresi argumen, yang mengharuskan kita untuk mengetahui tipe ITEM . Ini menciptakan lingkaran yang tidak bisa kita selesaikan, jadi kita kembali ke tipe implisit any .

Kita bisa memperbaikinya dengan meminta logika pengenalan tipe predikat terlebih dahulu menyelesaikan tipe objek fungsi dan memeriksa semua tanda tangan panggilan. Jika tidak satupun dari mereka adalah predikat tipe yang ditentukan pengguna, kita dapat menalangi lebih awal tanpa menyelesaikan ekspresi argumen panggilan, yang menghindari sirkularitas.

Sementara itu, Anda dapat memutus lingkaran hanya dengan menambahkan tanda kurung ke arg dalam panggilan ke otherFunc . Dengan kata lain, ubah panggilan menjadi otherFunc(ITEM, (arg)) . Hal ini menyebabkan penganalisis aliran kontrol tidak lagi mempertimbangkan panggilan tersebut sebagai kemungkinan pemanggilan predikat tipe yang ditentukan pengguna.

Semua 3 komentar

Ini adalah masalah analisis aliran kontrol. Untuk menyimpulkan tipe untuk ITEM kita perlu mencari tipe aliran kendali dari arg.arr . Itu berarti kita perlu melihat konstruksi yang mempengaruhi tipe arg . Ini termasuk panggilan ke otherFunc yang sepertinya _bisa_ menjadi predikat tipe yang ditentukan pengguna. Untuk menentukan apakah itu _is_ predikat tipe, kita menyelesaikan ekspresi panggilan, yang memerlukan penyelesaian ekspresi argumen, yang mengharuskan kita untuk mengetahui tipe ITEM . Ini menciptakan lingkaran yang tidak bisa kita selesaikan, jadi kita kembali ke tipe implisit any .

Kita bisa memperbaikinya dengan meminta logika pengenalan tipe predikat terlebih dahulu menyelesaikan tipe objek fungsi dan memeriksa semua tanda tangan panggilan. Jika tidak satupun dari mereka adalah predikat tipe yang ditentukan pengguna, kita dapat menalangi lebih awal tanpa menyelesaikan ekspresi argumen panggilan, yang menghindari sirkularitas.

Sementara itu, Anda dapat memutus lingkaran hanya dengan menambahkan tanda kurung ke arg dalam panggilan ke otherFunc . Dengan kata lain, ubah panggilan menjadi otherFunc(ITEM, (arg)) . Hal ini menyebabkan penganalisis aliran kontrol tidak lagi mempertimbangkan panggilan tersebut sebagai kemungkinan pemanggilan predikat tipe yang ditentukan pengguna.

@ahejberg
Terima kasih atas solusi tanda kurung.
Saya ingin mencari tahu ini. PR bisa diterima, bukan?

@arusakov Perbaiki sekarang di master!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat