Что означает "все юридические JavaScript законные TypeScript"?

Я часто слышу, как люди делают такие заявления

Весь код JavaScript является законным TypeScript code

Но все же, когда я написал совершенно законный и разумный JS-код, который имеет полностью детерминированное поведение:

var x = "hello".substr("w").toStrig * { m: 3 / true } + window + parseInt(Element).fzq;

ECMAScript определяет, что x должно иметь значение "NaN[object Window]undefined", которое кажется совершенно прекрасным, но я получил кучу ошибок от TypeScript! Разве это утверждение не означает, что "все JS является TS" ложью? Какая сделка?

Ответ 1

Весь код JavaScript является законным TypeScript code

Здесь это означает:

  • TypeScript не меняет синтаксис существующего JavaScript
  • TypeScript не изменяет поведение существующего JavaScript
  • TypeScript рассматривает некоторый JS-код, чтобы иметь предупреждения типа, , потому что точка

Синтаксис

TypeScript успешно проанализирует весь юридический код JavaScript. Он будет выдавать этот код как есть (минус downleveling, например, функции ES6 arrow будут преобразованы в эквивалентный код ES5, если вы настроите ES5 или ниже). Вы можете игнорировать предупреждения типа, созданные этим JS-кодом, если хотите; тип предупреждения не остановит TypeScript от записи выходного файла .js.

Поведение

TypeScript не изменяет поведение существующего кода JavaScript, хотя многие люди этого хотят! Любой JS-код, запускаемый через компилятор, будет вести себя так же, как если бы он запускался напрямую *.

Предупреждения типа

TypeScript может выдавать предупреждения типа на код, который он считает неправильным.

Что означает неправильное? Обратите внимание, что JavaScript детерминирован. Например, в отличие от С++, в принципе невозможно вызвать поведение, которое является "определяемым реализацией". JavaScript также очень редко вызывает исключения; в отличие от других языков, которые могут вызвать исключение при попытке умножить объект на функцию, JS создает NaN. Доступ к собственности с помощью неверного имени приведет к появлению undefined вместо ошибки времени выполнения (для многих огорчение). Таким образом, бар для "неправильного" здесь намеренно устанавливается более строго, чем "сбой вашего компьютера" или "выдает исключение".

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

var x = { } + 3; // Error, can't add objects and numbers
var y = "hello world".substr(1, 2, 3, 4, 5); // Error, too many parameters
var z = { x: 1, x: 2 }; // Error, duplicate property 'x'
var q = x[z]; // Error, indexing by an object doesn't really work...
var u = "hi".lenth; // Error, no property 'lenth' on string

Но spec!

Общий контраргумент выглядит следующим образом

"Спецификация ECMAScript определяет, что Math.max принуждает свои аргументы к числу, поэтому должно быть законным вызывать Math.max(someString, someOtherString)"

Верно, что спецификация ECMAScript явно определяет принуждения, которые происходят во время выполнения. Однако эта логика не дает нам никакого реального понимания. Взятая с его стороны, эта логика говорит, что, поскольку все параметры принуждаются к числу во время выполнения, должно быть законно писать

var x = Math.max("hello", window.setTimeout, { });

В конце концов, этот код имеет определенное поведение! Но это пропускает лес для деревьев - совершенно невероятно, что этот код правильный для любого разумного определения "правильного". TypeScript Существование основывается на понятии, что какой-то JavaScript-код неверен, и вы хотели бы узнать об этом.

Это ошибка категории, чтобы посмотреть спецификацию ECMAScript, которая предназначена для указания поведения, и решите, что это фактически нормативный документ, который описывает правильный код. Если вы хотите, вы можете работать с нигилистической теорией о том, что "все, что специфицирует спецификация, должно быть ОК" и использовать вариант TypeScript, который никогда не выдает предупреждения типа. Этот вариант широко доступен и называется "JavaScript".


*: Исключения из этого правила - это уровни вниз, которые могут иметь обнаруживаемые различия из-за ограничений во время выполнения, например. трассировки стека могут отличаться