Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Template Literal Typesであそぶ

m-yoshiro
August 23, 2021

Template Literal Typesであそぶ

Template Literal Typesはinferを組みあわせると色々遊べるのです。
Fukuoka.ts #3 の発表資料です。

参考資料
https://github.com/sindresorhus/type-fest

m-yoshiro

August 23, 2021
Tweet

More Decks by m-yoshiro

Other Decks in Technology

Transcript

  1. Template literal Typeを利用してできること • JSのテンプレートリテラルと同じ書式で Literal Types を作成できる • Literal

    Typesから一部の文字列を抽出したりできる • String.splitみたいな型も作れる Inferと組み合わせることで、
  2. (1) Literal Typesから番号だけ抽出する • TS Playground → sample // =>

    "39" type Result1 = IdNumber<'id-39'> type IdNumber<T extends string> = T extends `id-${infer U}` ? U extends `${number}` ? U : '' : ''
  3. (1) Literal Typesから番号だけ抽出する • TS Playground → sample // =>

    "39" type Result1 = IdNumber<'id-39'> type IdNumber<T extends string> = T extends `id-${infer U}` ? U extends `${number}` ? U : '' : '' ① Literal Typesのなかでinferを使う ② U はnumberであることを期待する
  4. (2) Literal Typesを分割してArrayを作る • TS Playground → sample type Split<S

    extends string> = S extends `${infer Head}${infer Tail}` ? [Head, ...Split<Tail>] : S extends "" ? [] : [S]; // => ['H', 'e', 'l', 'l', 'o'] type Result = Split<'Hello'>
  5. (2) Literal Typesを分割してArrayを作る • TS Playground → sample type Split<S

    extends string> = S extends `${infer Head}${infer Tail}` ? [Head, ...Split<Tail>] : S extends "" ? [] : [S]; // => ['H', 'e', 'l', 'l', 'o'] type Result = Split<'Hello'> ① 文字を分割するために inferを2つ使う ② 再帰させて文字を 全て走査する
  6. おまけ: Splitを使って文字数をカウント • TS Playground → sample type ArrayLength<Arr extends

    any[]> = Arr['length'] type StrLength<T extends string> = ArrayLength<Split<T>> // => 5 type Result2 = StrLength<'Hello'>
  7. (3) Camelcase → Snakecase // => my-friend-forever type Result =

    CamelToSnake<'myFriendForever'>; • TS Playground → sample
  8. (3) Camelcase → Snakecase • TS Playground → sample //

    1. 隣あう2文字を使ってCamelCaseかどうか判定する type IsCamelCase<First extends string, Second extends string> = Second extends "" ? false : First extends Lowercase<First> ? Second extends Capitalize<Second> ? true : false : false;
  9. (3) Camelcase → Snakecase // 2. IsCamelCaseを利用してハイフンを挿入していく type CamelToSnake<T extends

    string, Prev extends string = ''> = T extends `${infer Head}${infer Rest}` ? Rest extends string ? Rest extends "" ? `${Prev}${Head}` : IsCamelCase<Head, Rest> extends true ? CamelToSnake<Rest, `${Lowercase<Prev>}${Head}-`> : CamelToSnake<Rest, `${Lowercase<Prev>}${Head}`> : T : T