Typescript tells me property 'padStart' does not exist on type 'string'. Why?

TypeScript assumes by default that your transpiled code will run in the worst possible environment (for now, I hope, really the worst), i.e. in browser supporting only ES5. String.prototype.padStart is an experimental feature supported only in ES2017, so TypeScript can't be sure that at runtime it will be here and ready.

If you know that this "worst case" won't appear (you aren't targeting old browsers, or are using polyfills), you can make one of the following changes to your tsconfig.json:

  1. Change your transpilation target. This forces your consumers to have ES2017 (or newer) runtime, but requires no more effort from yourself. In this case, set target: "es2017".

  2. Change the list of libraries available. In this case, if you're not sure that your clients will be modern enough, you must provide them polyfills for the ES2017 elements you are using. In this case, add "es2017" to the array in lib parameter (if it was empty, then it will be lib: ["es2017"]).


To make TypeScript aware of String.prototype.padStart(), you need to specify es2017 in the list of libraries in your tsconfig.json. If you do that, then TypeScript will assume that all the ES2017 features can be used which might not be exactly what you want.

Platforms like Node.js don't always implement the complete feature set of a new ECMAScript language specification, so it's safer to only add the language features where you are confident that they exist. If you are not sure which features are supported by your targeted platform, you can look them up on pages likes node.green or MDNs browser compatibility list.

The padStart function is part of the String prototype, so it is sufficient to just add es2017.string in your tsconfig.json:

{
  "compilerOptions": {
    "lib": ["es6", "es2017.string"],
    ...
  },
}

padStart is defined in the ES2017 standard. You need to tell typescript to use the apropriate typings (the ones for ES2017). You can do this either by setting the target to ES2017, if your runtime supports all the language features required by ES2017 (which is probably not the case at the time of writing).

Another option is to just set the libs option in order to get the typings for runtime objects in accordance with ES2017 but still compile down to whatever language version you are targeting.(Note that the runtime itself needs to support padStart, typescript will not provide any poly-fills)

You can do this in tsconfig using the lib option:

"compilerOptions": {
    "target": "es2016",
    "lib": [
        "es2017",
        "dom"
        "scripthost"
    ],
    // ...

}

You can read more about lib vs target in this answer

Tags:

Typescript