gvergnaud / ts-pattern

🎨 The exhaustive Pattern Matching library for TypeScript, with smart type inference.
MIT License
12.51k stars 135 forks source link

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

Open titouancreach opened 10 months ago

titouancreach commented 10 months ago

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}`);
  })
  ...
cyberixae commented 8 months ago

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.

titouancreach commented 8 months ago

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