Typescript: --target ES5 does not compile ES5-compatible code (String.prototype.repeat) when libs are used

Created on 21 Jul 2018  路  9Comments  路  Source: microsoft/TypeScript


TypeScript Version: Version 2.9.2


Search Terms:
es5 string.prototype.repeat

Code

'a'.repeat(10);

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "./build",
    "target": "es5",
    "lib": ["es6", "dom"],
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "./",
  },
  "exclude": [
    "node_modules",
    "build"
  ]
}

Expected behavior:
Expecting String.prototype.repeat to be polyfilled or rewritten in the same manner that async/await syntax in transpiled correctly because the target is es5 and String.prototype.repeat is not part of ES5.

That is according to documentation

--target: Specify ECMAScript target version: "ES3" (default), "ES5", "ES6"/"ES2015", "ES2016", "ES2017" or "ESNext".

Actual behavior:
The expression appears as is

Playground Link:
https://github.com/agoldis/typescript-25853

Related Issues:
https://github.com/Microsoft/TypeScript/issues/3101

Duplicate

Most helpful comment

@DanielRosenwasser thanks for quick response. I mentioned the issue #3101 because it's the most relevant that I could find and auto-polyfilling would probably resolve the issue.

Let's face the fact:

  • documentation claims that using --target es5 creates ES5 compatible output, but it doesn't

If a user provides custom lib option, then TS will silently generate code that cannot be executed and could lead to exceptions in production (as in my case).

If auto-polyfilling is not an option, documenting the caveat properly or printing a warning or somehow preventing user from doing the mistake and investigating would make the job.

P.S.
Just out of curiosity - while async/await is transformed into a complex expression, why such a simple expression as String.prototype.repeat still needs to be figured out?

All 9 comments

3101 already contains a discussion around not polyfilling and I don't think much has changed since then.

@DanielRosenwasser thanks for quick response. I mentioned the issue #3101 because it's the most relevant that I could find and auto-polyfilling would probably resolve the issue.

Let's face the fact:

  • documentation claims that using --target es5 creates ES5 compatible output, but it doesn't

If a user provides custom lib option, then TS will silently generate code that cannot be executed and could lead to exceptions in production (as in my case).

If auto-polyfilling is not an option, documenting the caveat properly or printing a warning or somehow preventing user from doing the mistake and investigating would make the job.

P.S.
Just out of curiosity - while async/await is transformed into a complex expression, why such a simple expression as String.prototype.repeat still needs to be figured out?

Async/await is syntax that cannot be polyfilled because older javascript VMs cannot parse it. String.prototype.repeat is just a function that can simply be polyfilled.

And while I agree it is a pain-point, I still think that bring-your-own-polyfill has worked reasonably well for the most part.

documentation claims that using --target es5 creates ES5 compatible output, but it doesn't

Maybe the correct wording should be "ES5 compatible syntax"?

If the dev team considers this as not an issue please close it, I still think it is misguiding and error-prone :)

Thank you guys for your time!

From the moment you added "lib": ["es6", "dom"] to your tsconfig, you are explicitly saying "assume es6 library features will be available at runtime", and the compiler correctly did assume the feature would be there. If you load typings for es6, you most polyfill it.

My opinion: this is by design.

I have seen tag "design limitation" assigned to some issues - probably that's the proper tag for this one as well?

I actually see quite a nice description of --lib here:
https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#including-built-in-type-declarations-with---lib

and it mentions assuming runtime support of included declarations.

Hi, I am a facing an issue related to that problem. I was using TS 2.7.2 + core-js with ES5 target ES6 lib, and wanted to update to 3.1. Before it was generating proper ES5 code but now it produces ES6 code and some of this code is not being polyfilled by core-js, typically the property value shorthand like {pos} instead of {pos: pos}. What are the options to generate proper ES5 code ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

jbondc picture jbondc  路  3Comments

blendsdk picture blendsdk  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments