shabunc shabunc - 1 month ago 11
TypeScript Question

Typescript: why this code throws an exception while it is a 100% valid javascript code

It is claimed that TypeScript is a superset of Javascript.
Here's a question on Stack about this.
Here's a quote from spec:


TypeScript is a syntactic sugar for JavaScript. TypeScript syntax is a
superset of ECMAScript 2015 (ES2015) syntax. Every JavaScript program
is also a TypeScript program.


So my understanding is that any stand-alone javascript file can be treated as a valid typescript code, i.e. compiled (may be with some additional flags) by tsc compiler.

But here's an example of js code:

class ClassA {}
ClassA.prototype.ping = () => {console.log('PING')}


That is valid javascript but if you'll try to compile it with typescript, you'll get:
error TS2339: Property 'ping' does not exist on type 'ClassA'


One can declare interface which ClassA can implement, also, it's highly untypical to write code like this (combine class and prototype syntaxes) but nevertheless - this looks like an example of valid js code which won't be compiled in ts.

So the question is - how this does not contradict to the quote from spec?

Answer

TypeScript is a syntactic superset of JavaScript that doesn't change JavaScript's runtime behavior. So any expression or statement or declaration you write in JavaScript is syntactically legal TypeScript.

This doesn't mean that all JS code is considered to be warning-free TypeScript. After all, a major goal of TypeScript is to identify bad constructs like

var s = "hello world" * 423;
var t = "qzz".subtr(2);
var u = [1, 2, 3] + 5;
var w = window.navgtator;

These are all "valid" JavaScript expressions, they just happen to have undesirable runtime behavior that people don't want to actually do.

As usual in TypeScript, you can tell the type system about extra information

class ClassA {}
// Declare additional method
interface ClassA { ping(): void; }
// OK
ClassA.prototype.ping = () => {console.log('PING')}