Tür Testleri
Örnek Proje
Vitest, expectTypeOf veya assertType sözdizimlerini kullanarak türleriniz için testler yazmanıza olanak tanır. Varsayılan olarak *.test-d.ts uzantılı tüm dosyalar tür testi olarak kabul edilir, ancak bu davranışı typecheck.include yapılandırma seçeneğiyle değiştirebilirsiniz.
Vitest, yapılandırmanıza bağlı olarak arka planda tsc veya vue-tsc komutlarını çağırır ve sonuçları ayrıştırır. Kaynak kodunuzda tür hataları bulunursa, Vitest bunları da raporlayacaktır. Bu özelliği typecheck.ignoreSourceErrors yapılandırma seçeneğiyle devre dışı bırakabilirsiniz.
Vitest'in bu dosyaları çalıştırmadığını, yalnızca derleyici tarafından statik olarak analiz edildiğini unutmamak önemlidir. Bu, dinamik bir ad veya test.each veya test.for kullanırsanız, test adının değerlendirilmeyeceği ve olduğu gibi görüneceği anlamına gelir.
WARNING
Vitest 2.1'den önce, typecheck.include ayarınız include kalıbını geçersiz kılıyordu, bu nedenle çalışma zamanı testleriniz aslında çalışmıyordu; yalnızca tür kontrolü yapılıyordu.
Vitest 2.1'den beri, include ve typecheck.include ayarlarınız çakışıyorsa, Vitest tür testlerini ve çalışma zamanı testlerini ayrı öğeler olarak raporlayacaktır.
--allowOnly ve -t gibi CLI bayraklarının kullanımı da tür kontrolü için desteklenir.
import { assertType, expectTypeOf } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name string bekleniyor
assertType(mount({ name: 42 }));
});Bir test dosyasında tetiklenen herhangi bir tür hatası bir test hatası olarak ele alınacaktır, böylece projenizin türlerini test etmek için istediğiniz herhangi bir tür tekniğini kullanabilirsiniz.
Olası eşleşenlerin bir listesini API bölümünde görebilirsiniz.
Hataları Okuma
expectTypeOf API'sini kullanıyorsanız, expect-type belgelerindeki hata mesajlarına bakın.
Türler eşleşmediğinde, .toEqualTypeOf ve .toMatchTypeOf, hata mesajlarını mümkün olduğunca anlaşılır hale getirmek için özel bir yardımcı tür kullanır. Ancak bunları anlamanın belli bir nüansı vardır. Doğrulamalar "zincirleme" bir şekilde yazıldığından, hata "beklenen" türde olmalı, "gerçek" türde değil (expect<Actual>().toEqualTypeOf<Expected>()). Bu, tür hatalarının biraz kafa karıştırıcı olabileceği anlamına gelir - bu nedenle bu kütüphane, beklentinin ne olduğunu netleştirmek için bir MismatchInfo türü üretir. Örneğin:
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();Bu test, {a: 1} değerinin {a: number} türünde olduğu ve {a: string} olmadığı için başarısız olacaktır. Bu durumda hata mesajı şöyle görünecektir:
test/test.ts:999:999 - error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: \\"Expected: string, Actual: number\\"; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type '\\"Expected: string, Actual: number\\"'.
999 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>()Bildirilen tür kısıtlamasının hem "beklenen" hem de "gerçek" türleri belirten anlaşılır bir mesaj olduğunu akılda tutun. Types of property 'a' are incompatible // Type 'string' is not assignable to type "Expected: string, Actual: number" cümlesini harfiyen yorumlamak yerine, sadece özellik adına ('a') ve mesaja bakın: Expected: string, Actual: number. Bu, çoğu durumda neyin yanlış olduğunu size gösterecektir. Son derece karmaşık türlerin hata ayıklaması elbette daha fazla çaba gerektirecek ve biraz deneme yanılma gerektirebilir. Hata mesajları gerçekten yanıltıcıysa lütfen bir sorun kaydı oluşturun.
toBe... yöntemleri (toBeString, toBeNumber, toBeVoid vb. gibi), test edilen Actual türü eşleşmediğinde çağrılamaz bir türe dönüşerek başarısız olur. Örneğin, expectTypeOf(1).toBeString() gibi bir doğrulama için hata şöyle görünecektir:
test/test.ts:999:999 - error TS2349: This expression is not callable.
Type 'ExpectString<number>' has no call signatures.
999 expectTypeOf(1).toBeString()
~~~~~~~~~~This expression is not callable kısmı pek yardımcı değil - anlamlı hata bir sonraki satırda: Type 'ExpectString<number>' has no call signatures. Bu esasen bir sayı ilettiğiniz ancak bir string olması gerektiğini belirttiğiniz anlamına gelir.
TypeScript "throw" türleri desteği ekleseydi bu hata mesajları önemli ölçüde geliştirilebilirdi. O zamana kadar belirli bir miktar dikkatli inceleme gerektirecekler.
Somut "beklenen" nesneler ile tür argümanları
Şunun gibi bir doğrulama için hata mesajları:
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: '' });Şunun gibi bir doğrulama için olduğundan daha az yardımcı olacaktır:
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();Bunun nedeni, TypeScript derleyicisinin .toEqualTypeOf({a: ''}) için tür argümanını çıkarması gerekmesidir ve bu kütüphane bunu yalnızca genel bir Mismatch türüyle karşılaştırarak bir hata olarak belirleyebilir. Bu nedenle, mümkün olduğunda, .toEqualTypeOf ve toMatchTypeOf için somut bir tür kullanmak yerine bir tür argümanı kullanılması önerilir. İki somut türü karşılaştırmak daha uygunsa, typeof kullanabilirsiniz:
const one = valueFromFunctionOne({ some: { complex: inputs } });
const two = valueFromFunctionTwo({ some: { other: inputs } });
expectTypeOf(one).toEqualTypeOf<typeof two>();expectTypeOf API'si ile çalışmakta ve hataları anlamakta zorlanıyorsanız, her zaman daha basit assertType API'sini kullanabilirsiniz:
const answer = 42;
assertType<number>(answer);
// @ts-expect-error answer bir string değil
assertType<string>(answer);TIP
@ts-expect-error sözdizimini kullanırken, bir yazım hatası yapmadığınızdan emin olmanız önerilir. Bunu, tür dosyalarınızı test.include yapılandırma seçeneğine dahil ederek sağlayabilirsiniz, böylece Vitest bu testleri gerçekten çalıştıracak ve ReferenceError ile başarısız olacaktır.
Bu test başarılı olacaktır, çünkü bir hata beklenmektedir, ancak "answer" yerine "answr" yazılarak yapılan yazım hatası nedeniyle bu yanlış pozitif bir hatadır:
// @ts-expect-error answer bir string değil
assertType<string>(answr);Tür Kontrolünü Çalıştırmak
Tür kontrolünü etkinleştirmek için, package.json dosyanızdaki Vitest komutunuza --typecheck bayrağını eklemeniz yeterli olacaktır:
{
"scripts": {
"test": "vitest --typecheck"
}
}Şimdi tür kontrolünü çalıştırabilirsiniz:
npm run testyarn testpnpm run testbun testVitest, yapılandırmanıza bağlı olarak tsc --noEmit veya vue-tsc --noEmit kullanır, böylece bu komut dosyalarını derleme sürecinizden kaldırabilirsiniz.