Skip to content

.call selects the wrong overload for String.prototype.replace #29789

Open

Description

@ljharb

TypeScript Version: v3.3.1 and v3.4.0-dev.20190206

Search Terms: call replace overload

Code

String.prototype.replace.call(
    'one string',
    /a/g,
    'two string', // this line errors
);

It's worth noting that this is in a JS file, not a TS file, but I'm using allowJs and checkJs.

Expected behavior:
No error.

Actual behavior:
errors with error TS2345: Argument of type '"two string"' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'

Playground Link: http://www.typescriptlang.org/play/#src=String.prototype.replace.call(%0D%0A%20%20%20%20'one%20string'%2C%0D%0A%20%20%20%20%2Fa%2Fg%2C%0D%0A%20%20%20%20'two%20string'%2C%0D%0A)%3B but the error doesn't seem to show up there.

Related Issues: no

Activity

  1. RyanCavanaugh commented on Feb 14, 2019

    @RyanCavanaugh
    Member

    The additional overload in lib.es2015.symbol.wellknown needs to be a full union with the regular overload's parameters so that when .call finds it, the regular invocations are still OK.

  2. jaredh159 commented on May 20, 2019

    @jaredh159

    I'm pretty sure I've run into this same issue, but not using .call. This code snippet shows the problem:

    interface ReplacerFn {
      (substr: string, ...args: any[]): string;
    }
    
    function replaceMeStr(str: string, replacer: string) {
        return str.replace(/foo/, replacer); // works! :)
    }
    
    function replaceMeFn(str: string, replacer: ReplacerFn) {
        return str.replace(/foo/, replacer); // works! :)
    }
    
    function replaceMe(str: string, replacer: string | ReplacerFn) {
        return str.replace(/foo/, replacer); // <---  !!!!!!!!! --- !!!!!! --- error! :(
    }

    In the last example, the union of string | ReplacerFn (both of which are valid and work on their own, as demonstrated above) fails as typescript seems to only allow the function variant of the second param to String.replace, giving the error:

    Type 'string' is not assignable to type '(substring: string, ...args: any[]) => string'.

    Playground link:

    https://www.typescriptlang.org/play/index.html#src=interface%20ReplacerFn%20%7B%0D%0A%20%20(substr%3A%20string%2C%20...args%3A%20any%5B%5D)%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Afunction%20replaceMeStr(str%3A%20string%2C%20replacer%3A%20string)%20%7B%0D%0A%20%20%20%20return%20str.replace(%2Ffoo%2F%2C%20replacer)%3B%20%2F%2F%20works!%20%3A)%0D%0A%7D%0D%0A%0D%0Afunction%20replaceMeFn(str%3A%20string%2C%20replacer%3A%20ReplacerFn)%20%7B%0D%0A%20%20%20%20return%20str.replace(%2Ffoo%2F%2C%20replacer)%3B%20%2F%2F%20works!%20%3A)%0D%0A%7D%0D%0A%0D%0Afunction%20replaceMe(str%3A%20string%2C%20replacer%3A%20string%20%7C%20ReplacerFn)%20%7B%0D%0A%20%20%20%20return%20str.replace(%2Ffoo%2F%2C%20replacer)%3B%20%2F%2F%20error!%20%3A(%0D%0A%7D%0D%0A%0D%0A

  3. marcin-serwin commented on Nov 27, 2019

    @marcin-serwin
    Contributor

    Hi, Could I get any feedback on #34941?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions