TypeScriptは基本的に、JavaScriptに型注釈を追加しただけの言語です。
function hoge(num: number){
return num+1;
}
hoge(100); // 101
hoge("100"); // エラー
コンパイルすると型関連の文法が削除され、普通の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として動かなくなってしまいます。
enum Suit {
Hearts,
Diamonds,
Spades,
Clubs,
};
const suit = Suit.Clubs;
正しく動かすためには変換が必要です。
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で書いていくようにすると捗ることでしょう。