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 testleri 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ı analiz eder. Ayrıca, kaynak kodunuzda herhangi bir tür hatası bulunursa bunları da konsola yazdırır. Bu özelliği typecheck.ignoreSourceErrors
yapılandırma seçeneğiyle devre dışı bırakabilirsiniz.
Vitest'in bu dosyaları doğrudan çalıştırmadığını, yalnızca derleyici tarafından statik olarak analiz edildiğini unutmamak önemlidir. Bu, dinamik bir isim veya test.each
veya test.for
gibi yapılar kullanırsanız, test adının değerlendirilmeyeceği ve olduğu gibi görüntüleneceği anlamına gelir.
WARNING
Vitest 2.1 öncesinde, typecheck.include
ayarınız include
desenini geçersiz kılıyordu, bu nedenle çalışma zamanı testleriniz aslında çalışmıyor, yalnızca tür kontrolü yapılıyordu.
Vitest 2.1'den itibaren, include
ve typecheck.include
ayarlarınız çakışıyorsa, Vitest tür testlerini ve çalışma zamanı testlerini ayrı ayrı raporlayacaktır.
--allowOnly
ve -t
gibi CLI bayraklarının tür kontrolü için de desteklendiğini belirtmek gerekir.
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 bir string
assertType(mount({ name: 42 }));
});
Bir test dosyasında tetiklenen herhangi bir tür hatası, bir test hatası olarak ele alınacaktır. Bu sayede projenizin türlerini test etmek için istediğiniz herhangi bir tür tekniğini kullanabilirsiniz.
Olası eşleştiricilerin bir listesini API bölümünde bulabilirsiniz.
Hataları Okuma
expectTypeOf
API'sini kullanıyorsanız, expect-type belgelerindeki hata mesajlarına başvurabilirsiniz.
Türler eşleşmediğinde, .toEqualTypeOf
ve .toMatchTypeOf
mümkün olduğunca anlaşılır hata mesajları üretmek için özel bir yardımcı tür kullanır. Ancak bunları anlamanın küçük bir inceliği vardır. İddialar "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 açıkça belirtmek için bir MismatchInfo
türü oluşturur. Örneğin:
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();
Bu test, {a: 1}
türü {a: number}
olduğu ve {a: string}
olmadığı için başarısız olacaktır. Bu durumda hata mesajı şöyle bir şey gösterecektir:
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 unutmayın. 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 söyleyecektir. Son derece karmaşık türlerin hata ayıklaması elbette daha fazla çaba gerektirecek ve biraz deneme yapmayı gerektirebilir. Hata mesajları gerçekten yanıltıcıysa lütfen bir sorun açın.
toBe...
yöntemleri (toBeString
, toBeNumber
, toBeVoid
vb.) test edilen Actual
türü eşleşmediğinde çağrılamayan bir türe dönüşerek başarısız olur. Örneğin, expectTypeOf(1).toBeString()
gibi bir iddia için hata şöyle bir şey 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ır, Type 'ExpectString<number> has no call signatures
. Bu temelde bir sayı gönderdiğiniz halde string olması gerektiğini belirttiğiniz anlamına gelir.
TypeScript "throw" türleri için destek ekleseydi bu hata mesajları önemli ölçüde geliştirilebilirdi. O zamana kadar belirli bir miktar dikkatli inceleme gerektirecekler.
Somut "beklenen" nesneler vs tür argümanları
Şunun gibi bir iddia için hata mesajları:
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: '' });
Şunun gibi bir iddia için olanlardan daha az yardımcı olacaktır:
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();
Bunun nedeni, TypeScript derleyicisinin .toEqualTypeOf({a: ''})
stili için tür argümanını çıkarsaması gerekmesidir ve bu kütüphane bunu yalnızca genel bir Mismatch
türüyle karşılaştırarak bir hata olarak işaretleyebilir. Bu nedenle, mümkün olduğunda, .toEqualTypeOf
ve toMatchTypeOf
için somut bir tür kullanmak yerine bir tür argümanı kullanın. İki somut türü karşılaştırmak daha pratikse, typeof
kullanabilirsiniz:
const one = valueFromFunctionOne({ some: { complex: inputs } });
const two = valueFromFunctionTwo({ some: { other: inputs } });
expectTypeOf(one).toEqualTypeof<typeof two>();
expectTypeOf
API'si ile çalışırken ve hataları anlamakta zorlanıyorsanız, her zaman daha basit olan 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 olmak isteyebilirsiniz. Bunu, tür dosyalarınızı test.include
yapılandırma seçeneğine dahil ederek yapabilirsiniz, böylece Vitest bu testleri gerçekten çalıştıracak ve ReferenceError
ile başarısız olacaktır.
Bu geçecektir, çünkü bir hata bekliyor, ancak "answer" kelimesinde bir yazım hatası var, bu yüzden yanlış pozitif bir sonuçtur:
// @ts-expect-error answer bir string değil
assertType<string>(answr); //
Tür Kontrolünü Çalıştırma
Tür kontrolünü etkinleştirmek için, package.json
dosyanızdaki Vitest komutunuza --typecheck
bayrağını eklemeniz yeterlidir:
{
"scripts": {
"test": "vitest --typecheck"
}
}
Şimdi tür kontrolünü çalıştırabilirsiniz:
npm run test
yarn test
pnpm run test
bun test
Vitest, yapılandırmanıza bağlı olarak tsc --noEmit
veya vue-tsc --noEmit
kullanır, bu nedenle bu komut dosyalarını derleme sürecinizden kaldırabilirsiniz.