Property 'replaceAll' does not exist on type 'string'
Asked Answered
B

14

185

I want to use replaceAll in typescript and angular 10.

But I get this error: Property 'replaceAll' does not exist on type 'string'.

This is my code:

let date="1399/06/08"
console.log(date.replaceAll('/', '_'))

Output: 13990608

How can fix my typescript to show me this function?

Bower answered 27/8, 2020 at 12:57 Comment(4)
TypeScript can't magically add a function that your browser doesn't implement. You'll need to implement one of the replacement methods mentioned in the linked question in Michael D's answer.Murmur
date.split('/').join('_') you can use this as of now. Although you can update to chrome85.Pentobarbital
I want to use in vscode I have this error in vscodeBower
@Bower you can try with latest typescript version.Pentobarbital
H
184

You should be able to add those typings through your tsconfig.json. Add "ES2021.String" to lib inside compilerOptions.

Your tsconfig should then look something like this:

{
    ...,
    "compilerOptions": {
        ...,
        "lib": [
          ...,
          "ES2021.String"
        ]
    }
}

The replaceAll method is defined inside lib.es2021.string.d.ts as follows:

interface String {
    /**
     * Replace all instances of a substring in a string, using a regular expression or search string.
     * @param searchValue A string to search for.
     * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
     */
    replaceAll(searchValue: string | RegExp, replaceValue: string): string;

    /**
     * Replace all instances of a substring in a string, using a regular expression or search string.
     * @param searchValue A string to search for.
     * @param replacer A function that returns the replacement text.
     */
    replaceAll(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;
}
Hydrogeology answered 23/4, 2021 at 9:59 Comment(14)
found the lib.esnext.string.d.ts file the functions are declared as in your code not sure what you mean by "add those typings through your tsconfig.json" can you elaborateNorword
@KukulaMula I added a template to my answer. What I meant was, to add ESNext.String to lib inside you tsconfig.json.Hydrogeology
This removes the lint error but when I try to run, I get an error saying An unhandled exception occurred: tsconfig.json:21:7 - error TS6046: Argument for '--lib' option must be: 'es5', 'es6', 'es2015',... with a long list of options but none of them are ESNext.String and it won't compile.Anopheles
@StackUnderflow Maybe your TS version is too low, I believe it was added in TS 2.4, following this commitHydrogeology
@Hydrogeology mine is 3.8.3, not the latest but not too old.Anopheles
@StackUnderflow Not sure, you might have an entirely different problem. Search for the lib.esnext.string.d.ts file inside node_modules/typescript/lib, if its not there your versions don't match up. Or update/reinstall TS as a whole.Hydrogeology
@Hydrogeology You're right. I thought something was fishy because I updated it earlier, now I realize the version Angular is using doesn't match the global version. tsc -v shows 4.3.5 but ng --version shows 3.8.3. Any suggestions to resolve this?Anopheles
@Hydrogeology When I updated it I used npm install -g typescript@latest and this is what I find when I search for how to update the Angular typescript.Anopheles
@StackUnderflow That should update TS for you global ng but if not specified otherwise angular will use your local version if they don't match. Therefore you should skip the -g flag when updating you local repo.Hydrogeology
@Hydrogeology Yes, that looked like it was going to work but it seems like I need to upgrade Angular. I have Angular version 9.1.12 and it was complaining that it requires TypeScript >=3.6.4 and <3.9.0 but 4.3.5 was found instead. Thanks for your help.Anopheles
this worked for me in react-native mixed ts and js project I added them in tsconfig.json and jsconfig.json files as: "lib": ["es6", "ES2021.String"]Threephase
Surely this is just like adding a .d.ts file? It doesn't actually add a shim / polyfill for older browsers. iOS 12/13 still would need a polyfill. So I'm very confused why nobody else has mentioned that. Sure for Chrome this is fine but not older Safari.Edmonton
Very old browsers would need a polyfill, but it' actually quite well supported.Hydrogeology
write in lowercase if it doesn't work "es2021.String"Inconsonant
L
135

You may solve the problem using RegExp and global flag. The global flag is what makes replace run on all occurrences.

"1399/06/08".replace(/\//g, "_") // "1399_06_08"
Lurk answered 27/8, 2020 at 13:1 Comment(3)
this doesn't "resolve the problem". This is another way to replace all the occurrences. But if you want to continue using replaceAll, this doesn't resolve the issue of the OP.Eonism
This question is about TypeScript compatibility with String.replaceAll() not a request for a workaround.Lapillus
@Eonism In my case it solved the issue. I'm using react native and changing the compiler options doesn't actually update the javascript, so this is really the only solution.Keele
J
19

From the docs:

As of August 2020 the replaceAll() method is supported by Firefox but not by Chrome. It will become available in Chrome 85.

Meanwhile you could find multiple other methods here.

Screenshot for possible future readers:

enter image description here

Jhelum answered 27/8, 2020 at 12:58 Comment(3)
how can fix my typescript to show me this function??Bower
See also caniuse.com/#feat=mdn-javascript_builtins_string_replaceallMurmur
@behroozbc: AFAIK, replaceAll() is from ES2021 spec. If the latest version of TS doesn't support it, you can't do much except use one of the other methods.Jhelum
G
11

Just Use this function

    let date="1399/06/08"
    
    console.log(date.split('/').join('_'))
Gunsmith answered 18/11, 2020 at 7:36 Comment(2)
This was my first thought to solve my problem, but I'm sure there's a more efficient way. Using a RegEx seems the way to goSisak
The question asked is "How can fix my typescript to show me this function?". A valid answer obviously is not "use my function instead", even more when there is a clean answer to that (fix the ES version) :)Agamogenesis
A
11

That is because TypeScript does not recognize newer methods, than his current JavaScript version. String.replaceAll() is defined is ES2021.

You have to add the lib in compilerOptions, on the tsconfig.json file.

The value of lib must be either: ["ES2021"], or specifically the string typing ["ES2021.String"].

Add the following on the tsconfig.json file:

{
  ...
  "compilerOptions": {
    "lib": ["ES2021"]
  ...
}
Algesia answered 18/11, 2022 at 15:4 Comment(1)
this isn't removing my error for some reasonMelesa
A
7

You can create a file

myOwnTypes.d.ts

at the root of your angular project and add the following code:

interface String {
    replaceAll(input: string, output : string): any;
}

That will tell typescript that strings has this property.

Now replaceAll is supported in Chrome and Firefox but is always good to check the caniuse to check if it fits your needs.

https://caniuse.com/?search=replaceAll

If this works for you upvotes are more than welcome, Im starting with this stackoverflow account and would appreciate the support :)

Afebrile answered 14/3, 2021 at 22:27 Comment(0)
H
4

If anyone is still having this issue, add this to your tsconfig.json

{
    ...,
    "compilerOptions": {
        ...,
        "lib": [
          ...,
          "esnext.string"
        ]
    }
}
Hibernicism answered 15/12, 2022 at 8:35 Comment(0)
S
4

Another possible solution: I had this issue but my tsconfig target was set to "es2021". The cause, there was also one lib being specified. So by using the lib and the target, it overrided the defaults to the lib. The solution completely remove the lib or add it to the lib options.

Example: "compilerOptions":{ ..."target": "ES2021" }

or

"complierOptions":{
"target": "ES2021", "lib": [ ..., "ES2021.String" ],

Saxony answered 22/5, 2023 at 17:49 Comment(2)
This worked for me. I also had to make sure that my package was set to Node > 15 as well my active Node interpreter with nvmWillyt
wow this worked for me too, thanks!Rachael
S
3

A simple alternative to replace all using RegExp.

let subject = '1399/06/08';

let substring = '/';
let replacement = '_';

let newSubject = subject.replace(new RegExp(substring, 'g'), replacement);

console.log(newSubject);

Notice that you can make it as a function that takes substring and replacement as string inputs, which is practical.

My use-case was creating an Angular "Replace" Pipe.

Sericin answered 11/1, 2023 at 14:54 Comment(0)
M
2

This can also happen with a correct tsconfig if the file is not used/imported anywhere and not part of tsconfig.files

Materialize answered 25/3, 2023 at 11:13 Comment(1)
This helped solve my problem, thanks. My issue was I was missing files in the includes part of my tsconfig.json. Updating includes by adding my scripts directory fixed it.Coimbra
H
1

Chrome supports replaceAll so it is safe to use. However typescript still issues an error, so you may cast your string to any, in order to overcome that obstacle.

const date: any ="1399/06/08"
console.log(date.replaceAll('/','_'))
Homoeo answered 18/11, 2020 at 7:23 Comment(2)
please do not suggest to use anyTuchman
Changing to any is not a solution !!!Etiolate
L
0

According to MDN Web Docs,

"to perform a global search and replace, include the g switch in the regular expression".

So, you can try doing:

const date="1399/06/08"
const forwardSlashRegex = /(\/)/g;
console.log(date.replace(forwardSlashRegex, '_'));

This automatically replaces all forward slashes with the underscore. Make sure to also keep the /g global indicator at the end of the regex, as it allows JS to know that you want to replace ALL places where the forward slash occurs.

For more info on the use of regex indicators, refer to the following very useful guide: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

Lincoln answered 17/4, 2021 at 23:32 Comment(0)
C
0

In latest versions, you need to set the target attribute in compilerOptions.

{
"compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2021", // add this line to use ES2021
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false,
    "noUnusedLocals": false,
    "paths": {
        "@/*": ["src/*"],
        "@auth/*": ["src/auth/*"],
        "@aws/*": ["src/aws/*"],
        "@common/*": ["src/common/*"],
        "@conig/*": ["src/conig/*"],
        "@schemas/*": ["src/schemas/*"],
    }
}}
Churchyard answered 6/1, 2023 at 7:32 Comment(0)
C
0

I had the same issue. It seems like the issue is due to primitive string. I converted my string variable to String object and then the replaceAll() method did not cause runtime error.

Chlordane answered 2/4, 2023 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.