Open didavid61202 opened 1 year ago
Hi @gvergnaud , thanks for the suggestion and reporting the bug! I've fix the bug you mention in 0.1.16
// β
working now
type res2 = Call<Strings.Replace<"/([a-z][A-Z]|!)/g", "_$1_", "OaaObbOcc!">>;
type test2 = Expect<Equal<res2, "Oa_aO_b_bO_cc_!_">>;
for making the regex syntax opt-in, with
Call<
Strings.Replace<
Strings.Regex<"/([A-Z]|!)/g">,
"_$1_",
"OaaObbOcc!"
>
>;
I think this might only separate and make the parsing
part opt-in but not the evaluation/matching
part?
as currently we still check if the user pass in just string
or a RegExp
pattern in ReplaceReducer
interface:
export interface ReplaceReducer<To extends string> extends Fn {
return: this["args"] extends [
infer Str extends string,
infer From extends string,
...any
]
? Str extends Str
? From extends `/${infer RegExp}/`
? ResovleRegExpReplaceOrError<Str, RegExp, To, never>
: From extends `/${infer RegExp}/${SupportedRegExpReplaceFlags}`
? ResovleRegExpReplaceOrError<
Str,
RegExp,
To,
Split<
From extends `/${RegExp}/${infer Flags extends SupportedRegExpReplaceFlags}`
? Flags
: never,
""
>[number]
>
: Replace<Str, From, To>
: never
: never;
}
but I'm curious if this way is already making RegExp parsing
and evaluation
opt-in as the type-level RegExp will not infer type if user only pass in pure string?
Or if we want to fully separate the types, maybe we can achieve by introducing Strings.RegExpReplace
, Strings.RegExpMatch
, Strings.RegExpMatchAll
and Strings.RegExpSplit
?
What do you think? which way do you prefer?
I'll be working on adding the support for Strings.Split
π
I think this might only separate and make the
parsing
part opt-in but not theevaluation/matching
part? as currently we still check if the user pass in juststring
or aRegExp
pattern inReplaceReducer
interface:
From my point of view the /${infer RegExp/
should be enough to not trigger any big perf issue. TS is really performant for inferring and parsing strings.
The issue i see is more about: what if i want to replace strings starting and ending with /
without them being interpreted as regexp ?
The solution i see is the @gvergnaud one :
type Regex<Regexpr extends string, Modifiers extends SupportedRegExpReplaceFlags = ""> = {
type: RegexpSymbol;
regex: Regexpr;
modifiers: Modifiers
>
export interface ReplaceReducer<To extends string> extends Fn {
return: this["args"] extends [
infer Str extends string,
infer From extends string | Regex<string>,
...any
]
? From extends Regex<infer RegExp, infer Flags>
? ResovleRegExpReplaceOrError<Str, RegExp, To, Flags>
: Replace<Str, From, To>
: never;
}
@ecyrbe good point! I think this is the best way to go π
Updates
type-level-regexp/regexp
to prevent global declaration side effects from the package.Strings.RegExp
to create a RegExp object with pattern, flags and parsed matches to use with other RegExp related hotscript fn, and returnsRegExpSyntaxError
error type with detailed error message if the provided RegExp pattern contains some syntax error (currently only show few types of error, WIP)Strings.Replace
to also accept RegExp pattern (/<pattern>/
) asfrom
arg to replace substring matched by the given pattern. Replace value also support special replacemnet patterns.Strings.Match
to match a string against a RegExp (supporti
andg
flags), returns a matched object with match array andindex
andgroups
properties.Strings.MatchAll
to match a string against a RegExp, return an array of match objects, each with a match array andindex
andgroups
properties.Note
I have kept the implementation of RegExp matching and replacing generic types in a separate package called type-level-regexp. This allows for faster iteration as it is still in the early stages, and more features and performance improvements are coming along the way.
Usage
Related issues
Resolve #33
Tasks