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

TSKaigi Hokuriku - oxc-transformとisolatedDeclar...

Avatar for teamLab teamLab PRO
November 26, 2025

TSKaigi Hokuriku - oxc-transformとisolatedDeclarationsで 手に入れるtscなし型定義ファイル生成

このスライドはTSKaigi Hokurikuの登壇に使用したスライドのアーカイブになります。

チームラボでは、フロントエンドエンジニアを募集しています。
少しでも、チームラボにご興味をお持ち頂けましたら、採用ページをご覧頂けますと幸いです。
https://www.team-lab.com/recruit/

TSKaigi Hokurikuは、TypeScriptの国内最大級技術カンファレンス「TSKaigi」の北陸地域版で、2025年11月に金沢で開催されたイベントです。
https://hokuriku.tskaigi.org/

Avatar for teamLab

teamLab PRO

November 26, 2025
Tweet

More Decks by teamLab

Other Decks in Technology

Transcript

  1. © teamLab Inc. tsdown (txc)とtsdown (oxc) tsdown (tsc) - tscが処理

    7 tsdown (oxc) - oxc-transformが処理 - ただし、isolatedDeclarations オプションの制約が必要 どちらもrolldown-plugin-dtsを使っているが、.tsからd.tsを作る部分に違いがある
  2. © teamLab Inc. tsdown (txc)とtsdown (oxc) tsdown (tsc) - tscが処理

    8 tsdown (oxc) - oxc-transformが処理 - ただし、isolatedDeclarations オプションの制約が必要 どちらもrolldown-plugin-dtsを使っているが、d.tsを作る部分に違いがある 型関係を処理できるのはtscだけでは?🤔
  3. © teamLab Inc. isolatedDeclarations とは exportされる関数や変数への明示的な型注釈を必須にする tsconfigのオプション ts5.5+より 10 const foo

    = () => { return Math.random(); }; export const bar = () => { // ~~~~~~~ // Function must have an explicit return type annotation with --isolatedDeclarations.(9007) return Math.random(); }; export const baz = (): number => { return Math.random(); }; playground
  4. © teamLab Inc. dts出力に型推論が不要になる のd.tsを出力するには Math.random の型を知る必要がある 13 // source.ts

    export const bar = () => { return Math.random(); }; // lib.es5.d.ts interface Math { /** Returns a pseudorandom number between 0 and 1. */ random(): number; }
  5. © teamLab Inc. d.ts出力に型推論が不要になる のd.tsを出力するには Math.random の型を知る必要がある 14 // source.ts

    export const bar = () => { return Math.random(); }; // lib.es5.d.ts interface Math { /** Returns a pseudorandom number between 0 and 1. */ random(): number; } // dist.d.ts export declare const bar: () => number;
  6. © teamLab Inc. d.ts出力に型推論が不要になる なら実装を知っている必要はない! 15 // source.ts export const

    baz = (): number => { return Math.random(); }; // dist.d.ts export declare const baz: () => number; 実装を落とすだけなので、tscは不要!
  7. © teamLab Inc. 型の解決がモジュールを跨がなくなる 16 import { type User, fetchUser

    } from "./user.ts"; import { type ResultAsync, Result } from "@praha/byethrow"; export const safeFetchUser = async (id: string): ResultAsync<User, Error> => { try { const user = await fetchUser(id); return Result.succeed(user); } catch (e) { return Result.fail(e); } } 型推論をしないなら、
  8. © teamLab Inc. 型の解決がモジュールを跨がなくなる 17 import { type User }

    from "./user.ts"; import { type ResultAsync } from "@praha/byethrow"; export declare const safeFetchUser: (id: string) => ResultAsync<User, Error>; 型推論をしないなら、 ./user.ts や @parha/byethrow の定義を見に行かなくてもよい モジュール内に閉じることが保証されるので、並列に処理出来る!
  9. © teamLab Inc. つらい 20 export const userSchema: z.ZodObject<{ name:

    z.ZodString; age: z.ZodNumber; detail: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: string; talkTitle: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: string; }, z.core.$strip>], "type">; }, z.core.$strip> = z.object({ name: z.string(), age: z.number().positive(), detail: z.discriminatedUnion("type", [ z.object({ type: "speaker", talkTitle: z.string() }), z.object({ type: "listener" }) ]), }); 😅 型推論を使えないということは、型推論の恩恵を受けられないということ......
  10. © teamLab Inc. isolatedDeclaration isolatedDeclarationの制約は厳しい - これダメなんだ、が結構ある - とはいえ、ライブラリにするようなコードでは、意外となんとかなるかも -

    例えば、JotaiはisolatedDeclarationが有効になっている - 末端のアプリケーションコードでは結構きつい気がする - 覚悟の度合いによって使うかどうかを決めよう - 型チェックを速くしたいだけなら、 @typescript-eslint/explicit-function-return-typeという選択肢も 21
  11. © teamLab Inc. まとめ - isolatedDeclarationsオプションによる制約により、 tsc以外によるdts生成が現実的になった - oxc-transform -

    bunup/dts - サードパーティのdts生成器を使うことで、現状2倍ほど速くdtsを生成できる - が、型推論に縛りが入るisolatedDeclarationの制約は厳しい - 通常の型チェックも速くなるはずなので、ビルド時以外の恩恵もある - とはいえきつい時はあるので、対象コードの特性によって使うかどうかを決めよう - ts-goが十分速いので、やっぱりtscで良いかもしれない 22
  12. © teamLab Inc. jotai 24 jotaiはisolatedDeclarationsが有効になっているので検証に持ってこい 設定を調整しつつtsdownでビルドしてみた Benchmark 1: pnpm

    tsdown --config tsdown.config.isolated-false.mts Time (mean ± σ): 1.107 s ± 0.074 s [User: 1.948 s, System: 0.165 s] Range (min … max): 1.041 s … 1.221 s 5 runs Benchmark 2: pnpm tsdown --config tsdown.config.isolated-true.mts Time (mean ± σ): 565.8 ms ± 32.7 ms [User: 620.8 ms, System: 104.6 ms] Range (min … max): 530.0 ms … 606.7 ms 5 runs Benchmark 3: pnpm tsdown --config tsdown.config.tsgo.mts Time (mean ± σ): 756.2 ms ± 235.7 ms [User: 956.7 ms, System: 222.4 ms] Range (min … max): 639.8 ms … 1177.2 ms 5 runs