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

Template Literal Typesであそぶ

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 Typesで
    あそぶ
    松本 芳郎 / 株式会社マネーフォワード
    Fukuoka TS #3

    View Slide

  2. 自己紹介
    松本芳郎
    ● 株式会社マネーフォワード 経費本部
    ● フロントエンドエンジニア
    ● 前職ではデザイナーでした
    ● Twitter @bennkyougirai

    View Slide

  3. 発表内容
    Template Literal Types で遊ぶ!

    View Slide

  4. Template literal Typeとは

    View Slide

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

    View Slide

  6. Template literal Typeを利用してできること
    ● JSのテンプレートリテラルと同じ書式で Literal Types を作成できる
    ● Literal Typesから一部の文字列を抽出したりできる
    ● String.splitみたいな型も作れる
    Inferと組み合わせることで、

    View Slide

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

    View Slide

  8. (1) Literal Typesから番号だけ抽出する
    ● TS Playground → sample
    // => "39"
    type Result1 = IdNumber<'id-39'>
    type IdNumber = T extends `id-${infer U}`
    ? U extends `${number}`
    ? U : ''
    : ''
    ① Literal Typesのなかでinferを使う
    ② U はnumberであることを期待する

    View Slide

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

    View Slide

  10. (2) Literal Typesを分割してArrayを作る
    ● TS Playground → sample
    type Split = S extends `${infer Head}${infer Tail}`
    ? [Head, ...Split]
    : S extends ""
    ? []
    : [S];
    // => ['H', 'e', 'l', 'l', 'o']
    type Result = Split<'Hello'>
    ① 文字を分割するために inferを2つ使う
    ② 再帰させて文字を
    全て走査する

    View Slide

  11. おまけ: Splitを使って文字数をカウント
    ● TS Playground → sample
    type ArrayLength = Arr['length']
    type StrLength = ArrayLength>
    // => 5
    type Result2 = StrLength<'Hello'>

    View Slide

  12. (3) Camelcase → Snakecase
    // => my-friend-forever
    type Result = CamelToSnake<'myFriendForever'>;
    ● TS Playground → sample

    View Slide

  13. (3) Camelcase → Snakecase
    ● TS Playground → sample
    // 1. 隣あう2文字を使ってCamelCaseかどうか判定する
    type IsCamelCase =
    Second extends "" ? false : First extends Lowercase
    ? Second extends Capitalize ? true : false
    : false;

    View Slide

  14. (3) Camelcase → Snakecase
    // 2. IsCamelCaseを利用してハイフンを挿入していく
    type CamelToSnake =
    T extends `${infer Head}${infer Rest}`
    ? Rest extends string
    ? Rest extends ""
    ? `${Prev}${Head}`
    : IsCamelCase extends true
    ? CamelToSnake}${Head}-`>
    : CamelToSnake}${Head}`>
    : T
    : T

    View Slide

  15. ちなみに
    ● LowercaseやCapitalizeなどはTypeScriptがビルトインで提供してる
    ○ https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#intrinsic-string-ma
    nipulation-types

    View Slide

  16. コツ
    ● inferとTemplate Literal Types を組み合わせて推量対象の構造を作る
    ● Arrayとことで自由度がます
    ● 再帰を使う

    View Slide

  17. 最後に注意点
    ● 再帰を多用するので、パフォーマンスに影響ある可能性が。
    ● (検証してません)

    View Slide

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

    View Slide

  19. ご静聴ありがとうございました。

    View Slide