web-dev-qa-db-ja.com

TypeScriptは本当にJavaScriptのスーパーセットですか?

TypeScriptを使い始めたばかりですが、「宣言されていない変数の使用」というコンパイラエラーが発生することがあります。たとえば、以下はプレーンJavaScriptで機能します。

var foo = {};
foo.bar = 42;

TypeScriptで同じことを行おうとすると、機能せず、上記のエラーが発生します。私はそれをそのように書かなければなりません:

var foo :any = {};
foo.bar = 42;

プレーンJavaScriptでは、anyを使用した型定義は必須でも有効でもありませんが、TypeScriptではこれは必須のようです。私はエラーとその理由を理解していますが、私はいつもビデオで聞いて、ドキュメントを読みました:

typescriptlang.org

「TypeScriptはJavaScriptの型付きスーパーセットです[...]」

紹介ビデオ@分3:2

「すべてのJavaScriptコードはTypeScriptコードであり、単にコピーして貼り付けるだけです」

それはTypeScriptの開発中に変更されたものですか、それともこれを機能させるために特定のコンパイラ設定を渡す必要がありますか?

24
Markus

TypeScriptが存在する理由は、VanillaJavascriptよりも優れた型を適用できるコンパイラと言語を用意するためです。通常のJavascriptはすべて有効なTypeScriptです構文的に。これは、コンパイラが完全に満足している必要があるという意味ではありません。 Vanilla Javascriptには、タイプセキュリティの観点から問題のあるコードが含まれていることがよくあります。それではうまくいきませんinvalid TypeScriptコードですが、TypeScriptが存在するのはまさにその理由であり、これらの問題を指摘するのはまさにコンパイラの仕事です。

languagesそれ自体はまだお互いのサブ/スーパーセットです。

25
deceze

定理:TypeScriptはJavaScriptのサブセットでもスーパーセットでもありません。

証明:

言語Aが言語Bのサブセットであると言うとき、すべての有効なAプログラムが有効なBプログラムでもあることを意味します。

有効なJavaScriptプログラムではない有効なTypeScriptプログラムを次に示します。

let x: number = 3;

有効なTypeScriptプログラムではない有効なJavaScriptプログラムを特定しました。

var foo = {};
foo.bar = 42;

複雑な要因1:TypeScriptはほとんどスーパーセットです。 TypeScriptは、JavaScriptのほぼスーパーセットになることを目的としています。最も有効なJSは有効なTSでもあります。 JSにないものは、通常、TSでエラーなしでコンパイルするように簡単に調整できます。

複雑な要因2:致命的でないエラーTypeScriptコンパイラは、エラーが発生した場合でも、意図したJavaScriptコードを生成することがあります。以前に参照した例では、このエラーが発生します

error TS2339: Property 'bar' does not exist on type '{}'.

だけでなく、このJSコード

var foo = {};
foo.bar = 42;

TSドキュメント メモ

コードにエラーがある場合でも、TypeScriptを使用できます。ただし、この場合、TypeScriptは、コードが期待どおりに実行されない可能性があることを警告しています。

次の理由で、これをコンパイルの失敗(したがって無効なTypeScript)と呼ぶことができると思います。

  1. コンパイラは従来の意味でwarningという用語を使用しているようです。したがって、従来の意味でもerrorを解釈する必要があります。エラーはコンパイルが失敗したことを示します。
  2. 生成されたコードは期待どおりに実行できませんでした。それはまったく異なることをする可能性があります。 2つの言語AとBを想像してみてください。ここで、Aでコンパイルされる文字列はBでコンパイルされますが、まったく異なる動作をします。構文的にはAがBのサブセットであるとは言えません。
  3. ドキュメントには、結果のJavaScriptが意図したものに関して正しくないことが示されています。誤った出力は、出力がないのと同じくらい悪いように見えます(悪くはないにしても)。それらは両方とも失敗したと見なされるべきです。
  4. TypeScriptコンパイラはステータスコード2で終了します。これは通常、プロセスが何らかの方法で失敗したことを示します。
  5. JavaScriptを「有効」に出力するTypeScriptプログラムを呼び出す場合は、次のTypeScriptプログラムを有効と呼ぶ必要があります。

"

複雑な要因3:TSはJSファイルを受け入れます:TypeScriptコンパイラは.jsで終わるファイルをパススルーできます( コンパイラのドキュメント を参照) = for --allowJs)。この意味で、TypeScriptはJSのスーパーセットです。すべての.jsファイルはTypeScriptでコンパイルできます。これはおそらく、この質問にアクセスする人々が尋ねることを意味していることではありません。

複雑な要因1は、アンダース・ヘルスバーグが直面していることだと思います。また、TypeScriptのホームページでの誤解を招くマーケティングを正当化する可能性もあります。他の答えは複雑な要因2の餌食になっています。しかし、他の答えで与えられた一般的なアドバイスは正しいです。TypeScriptは、何か悪いことをしたときに通知するように設計されたJavaScriptの上のレイヤーです。それらは、さまざまな目的のためのさまざまなツールです。

8
charmoniumQ

定義

「すべてのJavaScriptコードはTypeScriptコードであり、単にコピーして貼り付けるだけです」

本当です。 任意のJavaScriptコードをTypeScriptコンパイラに渡すことができるため。

つまり、JavaScriptの上にあるレイヤーのようなものです。したがって、もちろん、下にあるレイヤー(JavaScript)は、レイヤーを介して最上位(TypeScript)に渡すことができますが、その逆はできません。

どうしてですか?

自転車(JavaScript)とオートバイ(TypeScript)と考えてください。基本は同じですが(2つのホイール、フレーム)、エンジンとしてのモーターサイクルといくつかの拡張機能があります。

つまり、バイク(TypeScript)をバイク(JavaScript)として使用することはできますが、バイクをバイクとして使用することはできません。

編集:

コンパイラが警告をスローした場合、なぜステートメントが間違っているのですか?それはただ言う:ねえ、あなたはTypeScriptを使っている、そしてそれはあなたが私に与えたものより厳しい。

この例を参照 、JavaScriptに完全にコンパイルされますが、警告がスローされます。

4
Bastian Gruber