Türleri Test Etme
Örnek Proje
Vitest, expectTypeOf
veya assertType
sözdizimlerini kullanarak türlerinizi test etmenizi sağlar. Varsayılan olarak *.test-d.ts
dosyalarındaki tüm testler tür testleri olarak kabul edilir, ancak bunu typecheck.include
yapılandırma seçeneğiyle değiştirebilirsiniz.
Vitest, arka planda yapılandırmanıza bağlı olarak tsc
veya vue-tsc
'yi çalıştırır ve sonuçları ayrıştırır. Vitest, kaynak kodunuzda herhangi bir tür hatası bulursa bunları da yazdırır. Bu özelliği typecheck.ignoreSourceErrors
yapılandırma seçeneğiyle devre dışı bırakabilirsiniz.
Unutmayın, Vitest bu dosyaları çalıştırmaz veya derlemez. Dosyalar yalnızca derleyici tarafından statik olarak analiz edilir. Bu nedenle, dinamik ifadeler kullanamazsınız. Dinamik test adları ve test.each
, test.runIf
, test.skipIf
, test.concurrent
API'lerini kullanamazsınız. Ancak test
, describe
, .only
, .skip
ve .todo
gibi diğer API'leri kullanabilirsiniz.
--allowOnly
ve -t
gibi CLI bayrakları da tür kontrolü için desteklenir.
import { assertType, expectTypeOf } from 'vitest';
import { mount } from './mount.js';
test('türlerim düzgün çalışıyor', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name bir string değil
assertType(mount({ name: 42 }));
});
Bir test dosyası içinde tetiklenen herhangi bir tür hatası, bir test hatası olarak kabul edilecektir. Bu nedenle, projenizin türlerini test etmek için dilediğiniz yöntemi kullanabilirsiniz.
Olası eşleştiricilerin bir listesini API bölümünde görebilirsiniz.
Hataları Okuma
expectTypeOf
API'sini kullanıyorsanız, expect-type'ın hata mesajları hakkındaki belgelerine bakın.
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 bazı incelikleri vardır. Doğrulamalar zincirleme şekilde yazıldığından, hata "gerçek" türde değil, "beklenen" türde olmalıdır (expect<Actual>().toEqualTypeOf<Expected>()
). Bu, tür hatalarının kafa karıştırıcı olabileceği anlamına gelir. Bu nedenle, bu araç, beklentinin ne olduğunu açıkça belirtmek için bir MismatchInfo
türü üretir. Örneğin:
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();
{a: 1}
türü {a: number}
olduğundan ve {a: string}
olmadığı için başarısız olacak bir iddiadır. Bu durumda hata mesajı şöyle bir şey olacaktır:
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}>()
Raporlanan tür kısıtlamasının hem "beklenen" hem de "gerçek" türleri belirten, insanlar tarafından kolayca anlaşılabilir bir mesaj olduğuna dikkat edin. 'a' özelliğinin türleri uyumsuz // 'string' türü "Beklenen: string, Gerçek: number" türüne atanamaz
cümlesini kelimenin tam anlamıyla almak yerine, yalnızca özellik adına ('a'
) ve mesaja bakın: Beklenen: string, Gerçek: number
. Bu size çoğu durumda neyin yanlış olduğunu söyleyecektir. Son derece karmaşık türlerin hata ayıklaması elbette daha fazla çaba gerektirecektir ve bazı denemeler gerektirebilir. Hata mesajları aslında yanıltıcıysa lütfen bir sorun bildirin.
toBe...
yöntemleri (toBeString
, toBeNumber
, toBeVoid
vb. gibi), test edilen Actual
türü eşleşmediğinde çağrılamayan bir türe çözümlenerek başarısız olur. Örneğin, expectTypeOf(1).toBeString()
gibi bir iddia için hata şöyle bir şey olacaktır:
test/test.ts:999:999 - error TS2349: This expression is not callable.
Type 'ExpectString<number>' has no call signatures.
999 expectTypeOf(1).toBeString()
~~~~~~~~~~
Bu ifade çağrılamaz
kısmı pek yardımcı değil. Asıl anlamlı hata bir sonraki satırda: Type 'ExpectString<number> has no call signatures
. Bu, aslında bir sayı gönderdiğiniz, ancak bunun bir string olması gerektiğini belirttiğiniz anlamına gelir.
TypeScript "throw" türleri için destek ekleseydi, bu hata mesajları önemli ölçüde iyileştirilebilirdi. O zamana kadar, bu hataları anlamak biraz çaba gerektirecek.
Somut "beklenen" nesneler ve tür argümanları
Şunun gibi bir iddia için hata mesajları:
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: '' });
Şunun gibi bir iddia için olduğundan 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ı çıkarması gerekmesidir ve bu araç bunu yalnızca genel bir Mismatch
türüne karşı karşılaştırarak bir hata olarak işaretleyebilir. Bu nedenle, mümkün olduğunca .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 çok daha kolaysa, 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 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ırır ve ReferenceError
ile başarısız olur.
Bu, bir hata beklediği için geçecektir, ancak "answer" kelimesinde bir yazım hatası olduğu için yanlış pozitif bir hata verecektir:
// @ts-expect-error answer bir string değil
assertType<string>(answr); //
Tür Kontrolünü Çalıştırma
Vitest 1.0'dan beri, tür kontrolü için package.json
dosyasındaki 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, böylece bu komut dosyalarını derleme sürecinizden kaldırabilirsiniz.