Действительно ли TypeScript надмножество JavaScript?

Я только начал использовать TypeScript и иногда получаю ошибки компилятора "использование незаявленной переменной". Например, следующее работает в обычном JavaScript:

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

Если я попытаюсь сделать то же самое в TypeScript, это не сработает и даст мне вышеупомянутую ошибку выше. Я должен написать так:

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

В простом JavaScript определение типа с любым не является ни обязательным, ни допустимым, но в TypeScript это кажется обязательным. Я понимаю ошибку и причину этого, но я всегда слышал в видео и читал в документации:

typescriptlang.org:

"TypeScript является типизированным надмножеством JavaScript [...]"

Введение Видео @minute 3:20:

"Весь код JavaScript - это код TypeScript, просто скопируйте и вставьте"

Это вещь, которая изменилась во время разработки TypeScript или мне нужно передать конкретный параметр компилятора, чтобы сделать эту работу?

Ответы

Ответ 1

Причина существования TypeScript заключается в том, чтобы иметь компилятор и язык, которые могут применять типы лучше, чем ванильный Javascript. Любой обычный Javascript действителен TypeScript, синтаксически. Это не значит, что компилятор должен быть полностью доволен этим. Ванильный Javascript часто содержит код, который является проблематичным с точки зрения безопасности типов. Это не делает его недействительным кодом TypeScript, но именно по этой причине TypeScript существует, и именно задание компилятора указывает на эти проблемы.

Языки как таковые все еще являются суб/надмножествами друг друга.

Ответ 2

Определение

"Весь код JavaScript - это код TypeScript, просто скопируйте и вставьте"

истинно. Поскольку любой код JavaScript может передаваться компилятору TypeScript.

Итак, это своего рода слой поверх JavaScript. Итак, конечно, слой Layer (JavaScript) можно передать через слои вверх (TypeScript), , но не наоборот.

Почему бы и нет?

Подумайте об этом как о велосипеде (JavaScript) и о мотоцикле (TypeScript). Основы одинаковы (два колеса, рама), но мотоцикл как двигатель и некоторые улучшенные функции.

Итак, вы можете использовать свой мотоцикл (TypeScript) в качестве байка (JavaScript), но вы не можете использовать велосипед в качестве мотоцикла.

ИЗМЕНИТЬ:

Если ваш компилятор выдает предупреждение, почему он делает выражение неверно? Он просто говорит: Эй, вы используете TypeScript, и это более строгим, чем то, что вы мне дали.

См. этот пример, он отлично компилируется для JavaScript, но выдает предупреждение.

Ответ 3

Теорема: TypeScript не является ни подмножеством, ни надмножеством JavaScript.

Доказательство:

Когда мы говорим, что язык A является подмножеством языка B, мы подразумеваем, что все действительные A-программы также являются действительными B-программами.

Вот допустимая программа TypeScript, которая не является допустимой программой JavaScript:

let x: number = 3;

Вы определили действительную программу JavaScript, которая не является допустимой программой TypeScript:

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. Сгенерированный код не может работать как ожидалось. Это может сделать что-то совершенно другое. Представьте себе два языка A и B, где любая строка, которая компилируется в A, компилируется в B, но делает что-то совершенно по-другому. Я бы не сказал, что A является подмножеством B, хотя это синтаксически.
  3. Документация указывает, что полученный JavaScript неверен относительно того, что было задумано. Неправильный вывод кажется таким же плохим, как (если не хуже, чем) отсутствие вывода. Их обоих следует считать несостоявшимися.
  4. Компилятор TypeScript завершает работу с кодом состояния 2, который обычно указывает, что процесс каким-то образом завершился неудачно.
  5. Если мы назовем любую программу TypeScript, которая выводит JavaScript "допустимым", то мы должны будем назвать следующую программу TypeScript допустимой:

"

Сложный фактор 3: TS принимает файлы JS: Компилятор TypeScript может проходить файлы, заканчивающиеся на .js (см. Документацию компилятора для --allowJs). В этом смысле TypeScript является надмножеством JS. Все файлы .js могут быть скомпилированы с помощью TypeScript. Вероятно, это не то, что люди, которые посещают этот вопрос, хотят задать.

Я думаю, что усложняющий фактор 1 - это то, к чему стремится Андерс Хейлсберг. Это также может оправдать вводящий в заблуждение маркетинг на домашней странице TypeScript. Другие ответы стали жертвой усложняющего фактора 2. Однако общие рекомендации, приведенные в других ответах, верны: TypeScript - это слой поверх JavaScript, разработанный для того, чтобы сообщать вам, когда вы что-то делаете плохо. Это разные инструменты для разных целей.