## 経緯 #2025/05/22 に[[Microsoft]]のブログで以下の記事が発表された。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2018/10/Microsoft-Favicon.png" /> <span class="link-card-v2-site-name">TypeScript</span> </div> <div class="link-card-v2-title"> Announcing TypeScript Native Previews - TypeScript </div> <div class="link-card-v2-content"> Previews of the native TypeScript port are now available on npm and for VS Code through the Visual Studio Market ... </div> <img class="link-card-v2-image" src="https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2018/08/typescriptfeature.png" /> <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-native-previews/"></a> </div> 2か月前に[[👤Anders Hejlsberg]]氏から発信された[[TypeScript]]の[[Go]]移植プレビュー版が[[npm]]でインストールできるようになった。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2018/10/Microsoft-Favicon.png" /> <span class="link-card-v2-site-name">TypeScript</span> </div> <div class="link-card-v2-title"> A 10x Faster TypeScript - TypeScript </div> <div class="link-card-v2-content"> Embarking on a native port of the existing TypeScript compiler and toolset to achieve a 10x performance speed-up ... </div> <img class="link-card-v2-image" src="https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2018/08/typescriptfeature.png" /> <a href="https://devblogs.microsoft.com/typescript/typescript-native-port/"></a> </div> [[VSCode Extension]]も用意されているようなので、[[VSCode]]で確認してみる。 ## 対象プロジェクト プロジェクトは[[🦉Various Complements]]を利用する。 ## インストール [[TypeScript 7]]をインストールする。 ```console pnpm add -D @typescript/native-preview ``` ## 動作確認 現在の型チェックコマンドがこう ```console pnpm exec tsc -noEmit -skipLibCheck ``` なので[[tsc]]を[[tsgo]]に変える。 ```console pnpm exec tsgo -noEmit -skipLibCheck ``` めちゃくちゃエラーが出た...。 ```error Found 810 errors in 10 files. Errors Files 731 node_modules/.pnpm/@[email protected]/node_modules/@codemirror/state/dist/index.cjs:12 9 node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/cedict.js:4 10 node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/main.js:29 19 node_modules/.pnpm/chinese-tokenizer@https+++codeload.github.com+tadashi-aikawa+chinese-tokenizer+tar.gz+3_3982f36683f7491dc77ca9b1040b1318/node_modules/chinese-tokenizer/src/trie.js:6 4 node_modules/.pnpm/[email protected]/node_modules/prettify-pinyin/index.js:23 32 node_modules/.pnpm/[email protected]/node_modules/style-mod/dist/style-mod.cjs:4 2 src/app-helper.ts:185 1 src/provider/InternalLinkWordProvider.ts:2 1 src/provider/suggester.test.ts:11 1 src/ui/popup-commands.ts:2 ``` [[allowJS]]と[[checkJs]]を無効化したらエラーは減った。 ```error src/app-helper.ts:185:20 - error TS2532: Object is possibly 'undefined'. 185 const text = markdownLink.matchAll(/^\[\[(?<text>.+)]]$/g).next().value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/app-helper.ts:189:35 - error TS2532: Object is possibly 'undefined'. 189 const { displayed, link } = markdownLink ~~~~~~~~~~~~ 190 .matchAll(/^\[(?<displayed>.+)]\((?<link>.+)\.md\)$/g) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 .next().value.groups!; // dirty error handling ~~~~~~~~~~~~~~~~~~~~~ src/provider/InternalLinkWordProvider.ts:2:32 - error TS2307: Cannot find module 'src/util/collection-helper' or its corresponding type declarations. 2 import { hasSameElement } from "src/util/collection-helper"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/provider/suggester.test.ts:11:27 - error TS2307: Cannot find module 'src/model/Word' or its corresponding type declarations. 11 import type { Word } from "src/model/Word"; ~~~~~~~~~~~~~~~~ src/ui/popup-commands.ts:2:45 - error TS2307: Cannot find module 'src/model/Word' or its corresponding type declarations. 2 import type { InternalLinkWord, Word } from "src/model/Word"; ~~~~~~~~~~~~~~~~ Found 5 errors in 4 files. Errors Files 2 src/app-helper.ts:185 1 src/provider/InternalLinkWordProvider.ts:2 1 src/provider/suggester.test.ts:11 1 src/ui/popup-commands.ts:2 ``` ## エラーの対処 [[ChatGPT]]([[o3]])に確認してもらった。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://cdn.oaistatic.com/assets/favicon-miwirzcw.ico" /> <span class="link-card-v2-site-name">ChatGPT</span> </div> <div class="link-card-v2-title"> ChatGPT - tsgo skipLibCheck 不具合 </div> <div class="link-card-v2-content"> Shared via ChatGPT </div> <img class="link-card-v2-image" src="https://cdn.oaistatic.com/assets/chatgpt-share-og-u7j5uyao.webp" /> <a href="https://chatgpt.com/share/6832a691-3850-800a-9c3b-db5016f1f4ce"></a> </div> ### TypeScriptのバージョンを5.5.4から5.8.3にアップデート 取り急ぎ、[[TypeScript]]のバージョンが古い(5.4)であることによる影響が大きそうなのでそこから。 ```console pnpm i typescript@latest ``` この状態で[[tsc]]のビルドをしてみる。 ```console $ pnpm exec tsc -noEmit ``` 2つエラーになった。 ```error src/app-helper.ts:185:20 - error TS2532: Object is possibly 'undefined'. 185 const text = markdownLink.matchAll(/^\[\[(?<text>.+)]]$/g).next().value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/app-helper.ts:189:35 - error TS2532: Object is possibly 'undefined'. 189 const { displayed, link } = markdownLink ~~~~~~~~~~~~ 190 .matchAll(/^\[(?<displayed>.+)]\((?<link>.+)\.md\)$/g) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 .next().value.groups!; // dirty error handling ~~~~~~~~~~~~~~~~~~~~~ Found 2 errors in the same file, starting at: src/app-helper.ts:185 ``` ### TS2532のエラーを修正する > TS 5.6 で導入された Strict Builtin Iterator Checks が tsgo では常時オン。next() の戻り値を done 確認せずに .value へアクセスすると未定義扱いになる > *[tsgo skipLibCheck 不具合](https://chatgpt.com/share/6832a691-3850-800a-9c3b-db5016f1f4ce)* `markdownLink.matchAll` の定義は ```ts matchAll(regexp: RegExp): RegExpStringIterator<RegExpExecArray>; ``` となっており、`RegExpStringIterator`の定義は ```ts interface RegExpStringIterator<T> extends IteratorObject<T, BuiltinIteratorReturn, unknown> { [Symbol.iterator](): RegExpStringIterator<T>; } ``` なので以下。 ```ts matchAll(regexp: RegExp): RegExpStringIterator<RegExpExecArray, BuiltinIteratorReturn, unknown>; ``` `BuiltinIteratorReturn` は [[intrinsic]] であり、[[strictBuiltinIteratorReturn]]のオプションによって決まる。 ```ts /** * Defines the `TReturn` type used for built-in iterators produced by `Array`, `Map`, `Set`, and others. * This is `undefined` when `strictBuiltInIteratorReturn` is `true`; otherwise, this is `any`. */ type BuiltinIteratorReturn = intrinsic; ``` [[strictBuiltinIteratorReturn]]をオフにするのは安全性を損なうので、[[非nullアサーション演算子 (TypeScript)|非nullアサーション演算子]]で対応する。 [[tsc]]としてのエラーはこれですべて消えるが、[[tsgo]]のエラーはまだ残っている。 ### 相対パスのインポートエラーを修正する 残されたエラーは以下。すべて相対パスに対するもの。 ```error src/provider/InternalLinkWordProvider.ts:2:32 - error TS2307: Cannot find module 'src/util/collection-helper' or its corresponding type declarations. 2 import { hasSameElement } from "src/util/collection-helper"; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/provider/suggester.test.ts:11:27 - error TS2307: Cannot find module 'src/model/Word' or its corresponding type declarations. 11 import type { Word } from "src/model/Word"; ~~~~~~~~~~~~~~~~ src/ui/popup-commands.ts:2:45 - error TS2307: Cannot find module 'src/model/Word' or its corresponding type declarations. 2 import type { InternalLinkWord, Word } from "src/model/Word"; ~~~~~~~~~~~~~~~~ Found 3 errors in 3 files. Errors Files 1 src/provider/InternalLinkWordProvider.ts:2 1 src/provider/suggester.test.ts:11 1 src/ui/popup-commands.ts:2 ``` `tsconfig.json` では [[baseUrl (tsconfig)|baseUrl]] を設定していた。 ```json { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "baseUrl": ".", } } ``` [[TypeScript 4.1からはbaseUrlは指定不要]]なので、相対パスで指定するように変更する。[[baseUrl (tsconfig)|baseUrl]]も`tsconfig.json`から削除。 > [!note] > [[paths (tsconfig)|paths]]に直接pathのマッピングを記載する方法もあるが、[[🦉Various Complements]]の場合は基本が相対パスなので、そちらにあわせる。 ## 速度の比較 キッカリ10倍になった。 ### tsc 0.5秒。 ```console $ pnpm exec tsc -noEmit --extendedDiagnostics Files: 200 Lines of Library: 39520 Lines of Definitions: 65039 Lines of TypeScript: 10326 Lines of JavaScript: 0 Lines of JSON: 0 Lines of Other: 0 Identifiers: 110983 Symbols: 96163 Types: 15527 Instantiations: 15182 Memory used: 154044K Assignability cache size: 2292 Identity cache size: 95 Subtype cache size: 342 Strict subtype cache size: 326 I/O Read time: 0.01s Parse time: 0.13s ResolveModule time: 0.02s ResolveTypeReference time: 0.00s ResolveLibrary time: 0.00s Program time: 0.19s Bind time: 0.07s Check time: 0.24s printTime time: 0.00s Emit time: 0.00s Total time: 0.51s ``` ### tsgo 0.05秒。 ```console $ pnpm exec tsgo -noEmit --extendedDiagnostics Files: 196 Lines: 111538 Identifiers: 108688 Symbols: 105470 Types: 23626 Instantiations: 21364 Memory used: 86248K Memory allocs: 429768 Parse time: 0.018s Bind time: 0.006s Check time: 0.025s Emit time: 0.000s Total time: 0.050s ``` ## VSCode Extensionを試す ブログで紹介されてた[[VSCode Extension]]を入れる。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://marketplace.visualstudio.com/favicon.ico" /> <span class="link-card-v2-site-name">marketplace.visualstudio.com</span> </div> <div class="link-card-v2-title"> TypeScript (Native Preview) - Visual Studio Marketplace </div> <div class="link-card-v2-content"> Extension for Visual Studio Code - Preview of the native TypeScript language server for Visual Studio Code. </div> <img class="link-card-v2-image" src="https://typescriptteam.gallerycdn.vsassets.io/extensions/typescriptteam/native-preview/0.20250523.1/1747986731351/Microsoft.VisualStudio.Services.Icons.Default" /> <a href="https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.native-preview"></a> </div> [[settings.json]]に追加。 ```json { "typescript.experimental.useTsgo": true } ``` 右下が以下のようになればOK。 ![[20250525_16_00_41.webp]] ## 今後について ### 型チェックについて [[TypeScript 7]]リリース時に切り替えるのは当然として、[[esbuild]]のように[[tsc]]でビルドをしていないプロジェクトに関しては、現時点で[[tsgo]]を使っていってもよさそう。影響は `tsc --noEmit` の部分しかないため、[[tsgo]]にした場合のリスクは以下の点くらいだと思う。 - [[tsc]]と型チェックの結果が異なるケースがある - 一部の[[tsc]]オプションに対応できていない [[tsc]]オプションの対応状況は若干気になるが、速度10倍は大きなメリット。デメリットについても以下の理由から許容範囲と考える - 今の[[tsc]]で動いているものなら、現時点までのデグレが発生するリスクは少ない - 今後の機能追加時には不整合が生じるリスクはある - [[tsc]]と[[tsgo]]を同時に依存関係に含めておけば、問題発生時に結果を比較できる - コミュニティに還元できるとなおGOOD 一方、以下に関しては少し慎重になりそう。 - [[Nuxt]]のプロジェクト - 仕事のプロジェクト すんなり導入できて安定していれば問題ないが、ハマったりすんなり移行できない場合は様子見したほうがよい。 ### エディタについて [[Neovim]]を引き続き利用していくつもりなので、こちらは[[tsc]]のままになると思う。[[tsgo]]を使うには[[VSCode]]が必要となるが、エディタでのパフォーマンスはそこまで困っていないため。 ただ、例外として、[[Zod]]が関係するコードは速度差がどれくらいあるかだけ試してみたいかも。現状が数秒ラグあるので。([[Zod]] v4で改善する可能性もあるが...)