Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
17
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

TypeScriptで型のユニットテストをしたい

やり方

準備

test.ts
export type TypeEq<A, B> = (<T>() => T extends A ? 1 : 2) extends (<
  T
>() => T extends B ? 1 : 2)
  ? true
  : false

export function assertType<_T extends true>() {}
export function assertNotType<_T extends false>() {}

色々複雑になっていますが、これは any や union、never などに対応するためです。
ここらへんの型は少し特殊なため、このようにしないと正常にテスト出来ません。

テストの書き方

assertType<TypeEq<1, 1>>()
assertNotType<TypeEq<1, 2>>()

テストが正しくなければコンパイルエラーが発生します。

import { TypeEq, assertType, assertNotType } from "./test"

assertType<TypeEq<1, 1>>()
assertNotType<TypeEq<{}, { x: 1 }>>()
assertNotType<TypeEq<1, 2>>()
assertNotType<TypeEq<1 | 2, 1>>()
assertNotType<TypeEq<1, never>>()
assertType<TypeEq<never, never>>()
assertNotType<TypeEq<1, any>>()
assertType<TypeEq<any, any>>()
assertNotType<TypeEq<1, unknown>>()
assertType<TypeEq<unknown, unknown>>()

そもそも何でこんなものが必要なの?

通常の TS の使い方なら必要ありません。
しかし、ts2.1 で Mapped types が入り、ts2.8 で Conditional Types が入り、ts3.0 で Tuple 関連の型システムが強化され TS の型システムはより複雑に、そして高機能になっています。
このような型システムをフル活用すると例えばタプル型をReverseZipするといったとても複雑な事を行えます。[参考](例えばZip<[1,2,3],[10,20]>は型[[1,10],[2,20]]を返すなど)
つまりtypeをただの型エイリアスではなく「型を受け取り型を返す関数」として使うことができます。
当然中身はかなり複雑ですし、バグも発生します。
関数のようなものなので正しい値を返してくれるかのテストを行いたいのです。

例えばさっきの例なら

assertType<TypeEq<Zip<[1, 2, 3], [10, 20]>, [[1, 10], [2, 20]]>>()

のように書くことでテストを行えます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
17
Help us understand the problem. What are the problem?