gvergnaud / ts-pattern

🎨 The exhaustive Pattern Matching library for TypeScript, with smart type inference.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deconstruct string matched with `.startsWith`, `.endsWith`, `regex`

titouancreach opened this issue · comments

Is your feature request related to a problem? Please describe.
I'm always frustrated when: I need to split the string manually after it matches .startsWith or .endsWith or regex (matching group).

For example I want to normalize phone number from a string
So, if it start with a "0" or "0033" I want to replace this number with "+33" (country code), if it starts with "+33", it's Ok.

match(phoneNumber)
  .with(P.string.startsWith("0033").select(), (matched) => {
    return "+33" + matched.slice(4);
  })
  ...

same with a regex:

match(phoneNumber)
  .with(P.string.regex("^0033([0-9]+)").select(), (matched) => {
    return "+33" + matched.slice(4); // if I want the group matched here, I need to manually re-execute the regex
  })
  ...

Describe the solution you'd like
I would like solution to match strings more like some other functionnal programming langage, example Elixir

iex> "he" <> rest = "hello"
"hello"
iex> rest
"llo"

Describe alternatives you've considered

Maybe select could be surcharged and select with a regex would give you "matches" (to be honest, I don't have a good idea of how it should be done)

match(phoneNumber)
  .with(P.string.startsWith("0033").select({ tail: true }), (matched, { tail }) => {
    return `+33${tail}`);
  })
  ...

or

match(phoneNumber)
  .with(P.string.startsWith("0033", 'tail').select(), (matched, { tail }) => {
    return `+33${tail}`);
  })
  ...

I made a feature request #227 about template literal matching support. Since your feature request is also related to strings, I thought that might be interesting to you. I also included a workaround that you might find useful, even though it might not be exactly what you are looking for.

@cyberixae Yes, it would solve 80% of my use cases