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

ts-morph実践:型を利用するcodemodのテクニック

 ts-morph実践:型を利用するcodemodのテクニック

TSKaigi 2025

Avatar for ypresto

ypresto

May 24, 2025
Tweet

More Decks by ypresto

Other Decks in Programming

Transcript

  1. ypresto © LayerX Inc. LayerX バクラク事業部 (2024-01〜) プロダクト開発部 債権債務チーム Software

    Engineer TypeScriptへのコントリビュート歴あり 宣伝の時間なんてないので採用サイトを 2
  2. codemod © LayerX Inc. AST (抽象構文木) を通して、機械的にコードを書き換える DOMツリーとHTMLの関係 = ASTとコードの関係、と考えると楽。

    ASTのNodeを探して書き換えると、コードが書き換わる jscodeshift:Meta製 例えばMUIのアップグレードのための @mui/codemod で使われている ts-morph: 型が使える← 今日 TypeScript Compiler API をゴリゴリとwrapしたライブラリ 5
  3. ts-morphを使う利点 jscodeshiftや、ラップされていないCompiler APIと比べて・・・ © LayerX Inc. node.findReferencesAsNodes() でエディタのように参照元を探せる node.getType() で型情報をチェックできる

    getTypeNode() で型注釈もすぐ取れる node.replaceWithText("const foo = 1") のように、 AST Nodeを組み立てず文字列で書き込める => 楽で安全な書き換え 6
  4. Cannot find name 'logger' sourceFile.organizeImports() せずにimportを足すのがむずい。 そもそもimport { A }

    from B のAとBをASTで扱うのがめんどい。 © LayerX Inc. console.error(e) → logger.caught(e) 12
  5. 2. 集めた型をこねて丸める Type Wideningがないと、 let foo = 1 に 2

    が入らなくなります。 © LayerX Inc. noImplicitAny: false を倒したい 18
  6. メソッドチェーンの呼び出しを探す © LayerX Inc. { baz: () => { ...

    } } のbazの呼び出しが、foo.bar.baz(1) になっていると き 愚直に祖先のcallを取ると、boo(foo.bar.baz) の boo() が取れてしまう ASTが読めると baz (Identifier) → foo.bar.baz (Property Access Expression) → foo.bar.baz(...) (Call Expression) とできる https://astexplorer.net/ を片手にやる 26