## 経緯
#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で改善する可能性もあるが...)