feature image

2022年7月29日 | ブログ記事

【TypeScript】型レベルでしりとりを判定する

突発ネタ記事です。Qittaに投げるのが怖かったのでここに投げます。

皆さんはTypeScriptを利用していて、「文字列の配列がしりとりとして成立しているかどうかを型レベルで判定したい」と思ったことはありますか?僕はありません。あるとしたらどこかで何かを間違えています。

しかしこういうことは 判定したい/したくない ではなく、できるからやる が大事です。やりましょう。

やりたいこと

type ShiritoriTest1 = isShiritori<["こぶた", "たぬき", "きつね", "ねこ"]>
// ↑ type Answer = true になってほしい

type ShiritoriTest2 = isShiritori<["真中らぁら", "南みれぃ", "北条そふぃ"]>
// ↑ type Answer = false になってほしい

これを目指します。

完成形

/** 文字列の最初の文字(のリテラル型)を返す型 */
type First<T extends string> = T extends `${infer L}${infer R}`
  ? (R extends ""
    ? L
    : First<L>
  )
  : undefined

/** 文字列の最後の文字(のリテラル型)を返す型 */
type Last<T extends string> = T extends `${infer L}${infer R}`
  ? (R extends ""
    ? L
    : Last<R>
  )
  : undefined

/** 文字列の配列がしりとりとして成立しているかを判定する型 */
type isShiritori<Words> = Words extends [infer FirstWord extends string, infer SecondWord extends string, ...infer Rest extends string[]]
  ? (FirstWord extends ""
    ? false
    : (Last<FirstWord> extends First<SecondWord>
      ? (Rest extends []
        ? true
        : isShiritori<[SecondWord, ...Rest]>
      )
      : false
    )
  )
  : false

type ShiritoriTest1 = isShiritori<["こぶた", "たぬき", "きつね", "ねこ"]>
// type ShiritoriTest1 = true

type ShiritoriTest2 = isShiritori<["真中らぁら", "南みれぃ", "北条そふぃ"]>
// type ShiritoriTest2 = false

TS Playground - An online editor for exploring TypeScript and JavaScript
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
Playgroundで試せます

解説

を、しようと思ったのですが、細かい解説は他サイト様の記事に任せて、これらの操作にどんな名前がついているかのみ簡単にまとめます。

TypeScriptの型機能については、型パズルで学ぶTypeScriptの型│FORCIA CUBE│フォルシア株式会社が詳しいのでぜひ一度お読みください。

型パズルで学ぶTypeScriptの型
TypeScriptには、他ではなかなか見られない型の機能が実装されています。本記事ではtype-challangesという、多くの型パズルが掲載されているサイトの主に文字列に関する問題を題材に、TypeScriptの型で遊んでみたいと思います。

ジェネリクス

ジェネリクス(Generics)は、(誤解を恐れずに言えば)"型を引数のように扱う"機能です。型定義のみならず、関数定義時やクラス定義時などでも利用できます。

<T extends string>のように、不等号の対<>で囲われた部分が"型を引数のように渡している"場所になります。

Conditional Types

Conditional Typesは、その名のとおり、"条件付きの型"を実現する型です。

R extends "" ? L : First<L>といった形で三項演算子のように記述することで、条件によって型を切り替えることができます。

Template Literal Types

Template Literal Typesは、JavaScriptにおける(通常の文字列としての)テンプレートリテラルの構文を使って、型を記述することができる機能です。

感想

Template Literal Types、恐ろしい子。

d_etteiu8383 icon
この記事を書いた人
d_etteiu8383

19の"でっていう"です グラフィック班とゲーム班所属 3DCGメインでいろいろ活動しています Vtuberっぽいこともしてたりしてなかったり

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2022年4月18日
350行でつくるVite⚡
sappi_red icon sappi_red
記事一覧 タグ一覧 Google アナリティクスについて