17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TypeScript5.8】erasableSyntaxOnlyフラグが導入されてNodeで動かせるようになる

Last updated at Posted at 2025-02-17

TypeScriptは基本的に、JavaScriptに型注釈を追加しただけの言語です。

TypeScript
function hoge(num: number){
    return num+1;
}

hoge(100);   // 101
hoge("100"); // エラー

コンパイルすると型関連の文法が削除され、普通のJavaScriptになります。

JavaScript
function hoge(num){
    return num+1;
}

hoge(100);   // 101
hoge("100"); // 1001

開発時はコードの間違いを見つけやすく、コンパイルすると普通のJavaScriptになってブラウザから実行可能です。

このようなJavaScriptの上位言語はaltJSと呼ばれ、CoffeeScriptやDartなど様々な言語が開発されました。
ここで多くの言語は正しい言語を目指し、JavaScriptの異常な挙動を排除し、結果としてJavaScriptとは全く異なる言語になりました。
そして、JavaScriptと全く同じ文法のTypeScriptが覇権を握りました。
ユーザは言語の正しさなんてものには興味がないから当然ですね。

とはいえTypeScriptも実際には削除可能コードだけできているわけではなく、TypeScript独自のコードも、特に初期のころは導入されていました。
有名どころではENUMで、これはJavaScriptには全く存在しないので削除するとJavaScriptとして動かなくなってしまいます。

TypeScript
enum Suit {
  Hearts,
  Diamonds,
  Spades,
  Clubs,
};
const suit = Suit.Clubs;

正しく動かすためには変換が必要です。

JavaScript
var Suit;
(function (Suit) {
    Suit[Suit["Hearts"] = 0] = "Hearts";
    Suit[Suit["Diamonds"] = 1] = "Diamonds";
    Suit[Suit["Spades"] = 2] = "Spades";
    Suit[Suit["Clubs"] = 3] = "Clubs";
})(Suit || (Suit = {}));
const suit = Suit.Clubs;

ところでNode.js 22.6.0--experimental-strip-typesというオプションが導入されました。
これはTypeScriptの実行コードから型関連コードを削除するというフラグです。
さらに23.6.0ではこれがデフォルトになり、逆に--no-experimental-strip-typesで否定しない限り常に型関連コードが削除されるようになりました。

すなわち、TypeScriptのコードはNode.jsでそのまま動作します。

ただし、名前のとおり型を削除するだけの処理であり、ENUMのような変換が必要なコードには対応していません。
これは実行速度との兼ね合いや、TypeScriptのコードに追随しなければならない危惧を考えた末の妥協点のようです。

そんなわけでNodeとTypeScriptが手を取り合った結果、TypeScript側にも、Nodeで削除可能なコードだけでできているかを確認できるフラグerasableSyntaxOnly導入されることになりました

このフラグを有効にしておくと、ENUMや名前空間などの削除可能ではないコードを使うとエラーになります。

すなわち、erasableSyntaxOnlyで開発したTypeScriptのコードはNode.jsでそのまま動作します。
やったね。

erasableSyntaxOnlyで許されない構文

ENUM

上記解説のとおりです。

enum X { }

namespace

JavaScriptには名前空間がありません。

namespace X {
  const x = 1;
}

constructorプロパティ割り当て

class X {
  constructor(public y) { }
}

これは単にpublicを消すだけではだめで、プロパティX.yを生やさないといけないので、削除では対応できません。

一部のimport文

import x = require('fs');
import A = e.p;

前者は適切な代替案がいまのところないそうです。

動かなくなる構文は以上のようです。
思ったより少ないですね。
これなら移行にもさほど苦労はしなさそうです。

erasableSyntaxOnlyでも許される構文

プロパティ可視性

class X {
  public y;
}

これはpublicを消せば動くのでOKです。

空のnamespace

namespace T {}

削除可能だから許されるそうです。
何に使うんだろうこれ。

感想

実はclassも、元々はTypeScriptが勝手に実装していたものがES2015で逆輸入されたという経緯があります。
つまり、下手したらclassすらerasableSyntaxOnlyで排除される可能性があったというわけです。
さすがにclassが使えなかったら致命傷だったと思うので、取り入れられていてよかったですね。

そんなわけで、方針が固まって軌道に乗った後のTypeScriptはともかく、開発当初のTypeScriptはわりとフリーダムだったみたいですね。

なお、なぜかENUMはclassと同じ波に乗れず、TypeScript独自実装のまま現在まで来てしまったわけですがどうしてでしょうか。
proposalを作っている人はいるのですが、TC39ではstage0にすら入ってないんですよね。
よくわかりません。

ということで、今後のTypeScriptはerasableSyntaxOnlyで書いていくようにすると捗ることでしょう。

17
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?