Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegExpMatchArray index 0 incorrectly possibly undefined when noUncheckedIndexedAccess is enabled #42296

Closed
DetachHead opened this issue Jan 12, 2021 · 7 comments Β· Fixed by #49682
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@DetachHead
Copy link
Contributor

DetachHead commented Jan 12, 2021

Bug Report

πŸ”Ž Search Terms

RegExpMatchArray noUncheckedIndexedAccess

πŸ•— Version & Regression Information

4.2.0-dev.20210112

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about noUncheckedIndexedAccess

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

const foo = "".match(/a/)
if (foo !== null) {
    const bar: string = foo[0] //Type 'string | undefined' is not assignable to type 'string'
}

πŸ™ Actual behavior

index 0 is of type string|undefined

interface RegExpExecArray extends Array<string> {
    index: number;
    input: string;
}

πŸ™‚ Expected behavior

index 0 should be of type string, since RegExpMatchArray will always have at least one value in it as when no matches are found, it returns null instead. see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#return_value

therefore we can be confident that if a RegExpMatchArray is returned, it will always have a length of at least 1

should be something like this:

type RegExpMatchArray = [string] & string[] & {
    index?: number;
    input?: string;
}
@RyanCavanaugh
Copy link
Member

I tried to fix this by adding 0: string to RegExpMatchArray, but it induces a different error in existing code that seems problematic:

    (''.match(/ /) || []).map(s => s.toLowerCase());

We'd need a fix that didn't create new other problems, IMO

@RyanCavanaugh RyanCavanaugh added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript labels Jan 12, 2021
@utkarshkukreti
Copy link

@RyanCavanaugh sorry I don't understand the problem with adding 0: string and that code snippet. Could you expand a bit?

@DetachHead
Copy link
Contributor Author

@utkarshkukreti from what i understand the compiler fails to infer the type since the type of the value on the right ([]) isn't assignable to the type of the value on the left ([string]).

here's a minified example https://www.typescriptlang.org/play?#code/MYewdgzgLgBAZiEMC8MDaByDBdGBDCGaAJwEswBzNbAHwFcwATAUznOcYFgAoH0SWACM8xFOiy4C6EuQq0GLNmA48+4aDGEAvMQiQB+femxqBMAI50AHmOGjDx1d20A6ALZ4ADgAo8KAHwwAN4AvgCUMAD0kQDuIMQA1hAANJrMwHh0EMzGMKSEfgBueAA2pIxEUGSU1DyWVu5evgHB4VGRjCDMEGAYsHGJaRlZOdR5hGAgsEWl5dJVsthAA

@utkarshkukreti
Copy link

@DetachHead thanks, I get it now. I hope someone figures out a solution, noUncheckedIndexedAccess is a game changer for type safety!

@GiancarlosIO
Copy link

GiancarlosIO commented May 13, 2021

is there a solution for this? or maybe it's the intended behavior?

@bob-difronzo
Copy link

Testing the examples from @RyanCavanaugh and @DetachHead in TypeScript 4.3.5 and above, both seem to work now:

I'm not sure if it would still be appropriate to add 0: string to RegExpMatchArray and RegExpExecArray, or if there is a better solution that could be implemented now.

@DetachHead DetachHead changed the title RegExpMatchArray index 0 incorrectly possibly undefined when noUncheckedIndexedAccess is enabled RegExpMatchArray index 0 incorrectly possibly undefined when noUncheckedIndexedAccess is enabled Apr 21, 2022
@DetachHead
Copy link
Contributor Author

#49682

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
5 participants