How 'endsWith' and other string functions are being generated in ES5 code

Viewed 286

I got an error of error TS2339: Property 'endsWith' does not exist on type 'string' while transpile ts to js.

When I search on google about it, I got an answer of 'endsWith' is ES6 function, target ts compiler to ES6".

I did the same, error gone. ES6 code generated.

the command was: tsc file-name.ts --target ES6

BUT if I did not target ES6, the error came, & still code transpile.

And I get valid ES.

As far as I know, until now, typescript is being transpile to ES5.

So, I get ES5 code because I did not target to ES6 at time of transpile.

the command was: tsc file-name.ts

Note: I removed the old .js file.

Then how 'endsWith' and other string functions are being generated in ES5 code? As they are ES6 function, and I did not target ES6.

1 Answers

There are two different sorts of things that new features of Javascript introduce: syntax and built-in objects/methods.

When you transpile (such as with Typescript, or from ESNext to ES5), you are translating the syntax of your code from its original version to ES5. For example:

const foo = 'foo'; // ES6 syntax

may become

var foo = 'foo';  // ES5 syntax

This does not affect non-syntax features. The following syntax is perfectly legal in ES5:

console.log(foo.endsWith('o'));

But just because the syntax is legal doesn't necessarily mean that what foo refers to has an endsWith property.

Those non-syntax features do not need transpiling, but rather, polyfilling - that is, if they do not exist in the environment, define them yourself. For example, one possible polyfill for endsWith is:

if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(search, this_len) {
    if (this_len === undefined || this_len > this.length) {
      this_len = this.length;
    }
    return this.substring(this_len - search.length, this_len) === search;
  };
}

If you make sure that the above code runs, you will not get the Property 'endsWith' does not exist on type 'string' error.

Most new objects/methods can be polyfilled, but some can't be, at least not fully accurately (eg Symbols and Proxyx, IIRC).

A popular service which provides polyfills for many newer objects/methods is polyfill.io.

To ensure that obsolete browsers can understand your code written in ESNext (or Typescript), use both transpilation and polyfills.

Related