generated at
PercentageParser<Str>


使用法
ts
type PString1 = '' type PString2 = '+85%' type PString3 = '-85%' type PString4 = '85%' type PString5 = '85' type R1 = PercentageParser<PString1> // expected ['', '', ''] type R2 = PercentageParser<PString2> // expected ["+", "85", "%"] type R3 = PercentageParser<PString3> // expected ["-", "85", "%"] type R4 = PercentageParser<PString4> // expected ["", "85", "%"] type R5 = PercentageParser<PString5> // expected ["", "85", ""]
文字列を引数にとって、符号、数字、単位に分ける

定義
ts
// prettier-ignore type PercentageParser<Str extends string> = Str extends `${Sign<Str>}${infer N}${Unit<Str>}` ? [Sign<Str>, N, Unit<Str>] : never; // prettier-ignore type Sign<Str extends string> = Str extends `+${string}` ? '+' : Str extends `-${string}` ? '-' : ''; type Unit<Str extends string> = Str extends `${string}%` ? '%' : '';


ポイント
Str extends \ ${Sign<Str>}${infer N}${Unit<Str>}\ の部分
unionで '+'|'-'|'' とやっているわけではない
扱いづらいのはnumberの部分なのでそこを残す
infer N
前からと、後ろからパターンマッチを同時にやっている感じ



こういう回答もある ref
ts
// prettier-ignore type PercentageParser<A extends string> = A extends `${CheckPrefix<infer L>}${infer R}` ? [L, ...CheckSuffix<R>] : ['', ...CheckSuffix<A>]; type CheckPrefix<T> = T extends '+' | '-' ? T : never; type CheckSuffix<T> = T extends `${infer P}%` ? [P, '%'] : [T, ''];
記述量が少ない
先に符号だけわけて、後から残りを処理する
CheckPrefix<infer L> の部分がおもろいmrsekut
こうすることで、パターンマッチに名前をつけてる感じのことをしている
普通に書いたらこうなるはず
ts
type PercentageParser<A extends string> = A extends `${infer S}${infer R}` ? S extends '+' | '-'     ? [S, ...CheckSuffix<R>] : ['', ...CheckSuffix<A>] // ① : ['', ...CheckSuffix<A>]; // ② type CheckSuffix<T> = T extends `${infer P}%` ? [P, '%'] : [T, ''];
文字列のパターンマッチで S を取り出した後に、
S '+' '-' かをチェックすることになる
イメージこんな感じ
ts
type Hoge<A extends string> = A extends `${T: '+'|'-'}${infer R}` ? T : never;
'+'|'-' にマッチさせつつ、 T という名前をつけている
でもそんな汎用性ないかmrsekut
1文字しか無理だし