type Percentage<P, S> = S extends `${infer N}%` ? [P, N, '%'] : [P, S, ''];
type PercentageParser<A> = A extends `${infer P extends '+' | '-'}${infer S}`
? Percentage<P, S> : Percentage<'', A>;
Solution by alexandroppolus #36333
type before = "-"|"+"
type after = "%"
type getPre<A extends string>= A extends `${infer first}${infer R}`? first extends before ? first:"":""
type getBack<A extends string>= A extends `${getPre<A>}${infer R}` ? R extends `${infer first}${after}`? after:"":""
type getNum <A extends string>= A extends `${getPre<A>}${infer R}${getBack<A>}` ? R:""
type PercentageParser <A extends string> = [getPre<A>,getNum<A>,getBack<A>]
get every part step by step.
Solution by 985025074 #36290
// your answers
//虽然很愚蠢,但还是通过了.
type PercentageParser<A extends string> =
A extends `${infer F}${infer R}`
? (F extends '+' | '-' ? [F, R] : ['', A]) extends [infer F, infer S]
? S extends `${infer M}%` ? [F, M, '%'] : [F, S, '']
: never
: ['', '', '']
Solution by goddnsgit #36197
type S4<Str, Result extends unknown[]> = Str extends '' ? Result : never
type S3<
Str,
Result extends unknown[],
> = Str extends `${infer First extends '%'}${infer Rest}`
? S4<Rest, [...Result, First]>
: S4<Str, [...Result, '']>
type S2<
Str,
Result extends unknown[],
N extends string = '',
> = Str extends `${infer First extends number}${infer Rest}`
? S2<Rest, Result, `${N}${First}`>
: S3<Str, [...Result, N]>
type S1<Str, Result extends unknown[]> = Str extends `${infer First extends
| '+'
| '-'}${infer Rest}`
? S2<Rest, [...Result, First]>
: S2<Str, [...Result, '']>
type PercentageParser<A extends string> = S1<A, []>
wiki: Nondeterministic_finite_automaton
Solution by Autumnal-Joy #36196
More verbose approach.
type NeverDefault<T, TDefault> =
[T] extends [never]
? TDefault
: T;
type GetSign<T extends string> =
T extends `${infer Sign extends '-' | '+'}${infer _}`
? Sign
: never;
type GetPercentageSign<T extends string> =
T extends `${infer Rest}%`
? '%'
: never;
type RemoveSign<T extends string> =
T extends `${ '-' |'+' }${infer Rest}`
? Rest
: T;
type RemovePercentageSign<T extends string> =
T extends `${infer Rest}%`
? Rest
: T;
type GetValue<T extends string> = RemovePercentageSign<RemoveSign<T>>;
type PercentageParser<T extends string> =
[
NeverDefault<GetSign<T>, ''>,
NeverDefault<GetValue<T>, ''>,
NeverDefault<GetPercentageSign<T>, ''>,
];
Solution by Rikkun-1 #36174
type CheckPrefix<T> = T extends '+' | '-' ? T : never;
type CheckSuffix<T> = T extends `${infer N}%` ? [N, '%'] : [T, '']
type PercentageParser<A extends string> = A extends `${CheckPrefix<infer L>}${infer R}` ? [L, ...CheckSuffix<R>] : ['', ...CheckSuffix<A>];
Solution by vaclock #35930
type PercentageParser<A extends string> = A extends `${infer F}${infer L}`
? F extends '-' | '+'
? L extends `${infer L1}%`
? [F, L1, '%']
: [F, L, '']
: A extends `${infer L2}%`
? ['', L2, '%']
: ['', A, '']
: ['', '', ''];
Solution by RanungPark #35577
// your answers
type PercentageParser<A extends string, S extends string = '', N extends string = '', P extends string = ''> = A extends `${infer First}${infer Rest}`
? First extends '+' | '-'
? PercentageParser<Rest, First, N, P>
: First extends '%'
? [S, N, '%']
: PercentageParser<Rest, S, `${N}${First}`, P>
: [S, N, P];
Solution by AndreGeng #34754
type PercentageParser<T extends string> =
T extends `${infer Start}${infer Middle}%` ?
Start extends '-' | '+' ?
[Start, Middle, '%'] : ["", `${Start}${Middle}`, '%'] :
T extends `${number}` ? ['', T, ''] : ['', '', ''];
Solution by semet #34677
// 你的答案
type CheckNumber<T extends string> = T extends `${infer Num}%`?[Num,"%"]:[T,""]
type PercentageParser<A extends string> =
A extends `${infer Sign extends '-'|'+'}${infer R}` ? [Sign,...CheckNumber<R>]:['',...CheckNumber<A>]
Solution by Jayce-liang #34634
type CheckSuffix<T> = T extends `${infer P}%` ? [P, '%'] : [T, ''];
type CheckPrefix<T> = T extends "+" | "-" ? T : never
type PercentageParser<A extends string> = A extends `${CheckPrefix<infer First>}${infer Rest}` ? [First, ...CheckSuffix<Rest> ] : ['', ...CheckSuffix<A>]
Solution by devshinthant #34628
type PercentageParser<A extends string> = A extends `${Perfix<infer P>}${infer V}` ? [P, ...Suffix<V>] : ['', ...Suffix<A>]
Solution by ouzexi #34043
// 你的答案
type DealRestLetters<T extends string> = T extends `${infer A}%` ? [A, '%'] : [T, '']
type PercentageParser<A extends string> = A extends `${infer T extends '+' | '-'}${infer F}` ? [T, ...DealRestLetters<F>] : ['', ...DealRestLetters<A>]
Solution by heyuelan #33695
type Num = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type PercentageParser<A extends string, C extends string[] = []> =
C['length'] extends 0
? A extends `${infer H}${infer R}`
? H extends '+' | '-'
? PercentageParser<R, [H]>
: PercentageParser<A, ['']>
: ['', '', '']
: C['length'] extends 1
? A extends `${infer H}${infer R}`
? H extends Num
? PercentageParser<R, [...C, H]>
: PercentageParser<A, [...C, '']>
: [...C, '', '']
: C['length'] extends 2
? A extends `${infer H}${infer R}`
? H extends Num
? PercentageParser<R, [C[0], `${C[1]}${H}`]>
: [...C, H]
: [...C, '']
: never
Solution by all-user #33120
type GetNumbersFromString<T extends string, Acc extends string = ""> = T extends `${infer F}${infer Rest}`
? F extends `${infer N extends number}` ? GetNumbersFromString<Rest, `${Acc}${N}`> : GetNumbersFromString<Rest, Acc>
: Acc
type GetOperatorFromPercentage<T extends string> = T extends `${infer O extends '+' | '-'}${string}` ? O : ''
type GetPercentageSymbolFromString<T extends string> = T extends `${string}${infer S extends '%'}` ? S : ''
type PercentageParser<T extends string> = [
GetOperatorFromPercentage<T>,
GetNumbersFromString<T>,
GetPercentageSymbolFromString<T>
]
Solution by ZhulinskiiDanil #32723
type CheckPrefix<T> = T extends '+' | '-' ? T : never;
type CheckSuffix<T> = T extends `${infer P}%` ? [P, '%'] : [T, ''];
type PercentageParser<A extends string> = A extends `${CheckPrefix<infer L>}${infer R}` ? [L, ...CheckSuffix<R>] : ['', ...CheckSuffix<A>];
처음에 Prefix, Value, Suffix의 개념으로 접근하여 풀지 못하였는데 위의 CheckSuffix 타입으로 한번에 원하는 타입을 만들 수 있는 방법을 새로 배웠다.
Solution by dev-hobin #32485
type NumberUnion = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
type AppendBlankString<T extends string[]> = T['length'] extends 2
?
[...T, '']
:
[...T, '', '']
type PercentageParser<A extends string, Acc extends string[] = [], NumAcc extends string = ''> = A extends `${infer H}${infer T}`
?
H extends NumberUnion
?
PercentageParser<T, Acc,`${NumAcc}${H}`>
:
H extends "%"
?
Acc extends []
?
PercentageParser<T, ["", NumAcc, H],`${NumAcc}`>
:
PercentageParser<T, [...Acc, NumAcc, H],`${NumAcc}`>
:
PercentageParser<T, [...Acc, `${H}`],`${NumAcc}`>
:
Acc['length'] extends 3
?
Acc
:
Acc extends []
?
["", NumAcc, ""]
:
AppendBlankString<[...Acc, NumAcc]>```
Solution by keyurparalkar #32330
type PercentageInternal<T> =
T extends `${infer A}%`
? [A, '%']
: [T, '']
;
type PercentageParser<T extends string> =
T extends `${infer Head}${infer Tail}`
? Head extends '+' | '-'
? [Head, ...PercentageInternal<Tail>]
: ['', ...PercentageInternal<T>]
: ['', '', '']
;
Solution by sdrjs #31486
// your answers
type PercentageParser<A extends string,
First extends string = A extends `${infer F extends '+' | '-'}${infer _}` ? F : '',
Last extends string = A extends `${infer _}%` ? '%' : ''
> = [
First,
A extends `${First}${infer _}${Last}` ? _ : never,
Last
]
Solution by yangdonglai #30733
type CheckL<T extends string> = T extends `${ infer U }%` ? [U, '%'] : [T, '']
type PercentageParser<A extends string> = A extends `${ infer B extends '+' | '-' }${ infer C }` ? [B, ...CheckL<C>] : ['', ...CheckL<A>]
Solution by Yirujet #30466
This approach is to iterate the input string letter by letter and check the first letter in each iteration and save each symbol to return in placeholders defined in the genric types until the iteration process has reached the end when A becomes an empty string, then we return the collected results in an array.
type PercentageParser<A extends string, Operator = '', Number = '', Percentage = ''> =
A extends `${infer Head}${infer Rest}`
? Head extends '+' | '-' ? PercentageParser<Rest, Head>
: Head extends '%' ? PercentageParser<Rest, Operator, Number, Head>
: PercentageParser<Rest, Operator, `${Number & string}${Head}`>
: [Operator, Number, Percentage]
Solution by qianzhong516 #30029
type PercentageParser<A extends string, S = '', U = ''> =
A extends `${infer S extends '+' | '-'}${infer R}` ? PercentageParser<R, S, U> :
A extends `${infer R}%` ? PercentageParser<R, S, '%'> :
[S, A, U]
Solution by sbr61 #29984
type GetPercent<A extends string> = A extends `${infer Rest}%` ? [Rest, "%"] : [A, ""]
type GetSign<A extends [string, "" | "%"]> =
A[0] extends `+${infer Rest}` ?
["+", Rest, A[1]] :
A[0] extends `-${infer Rest}` ?
["-", Rest, A[1]] :
["", A[0], A[1]]
type PercentageParser<A extends string> = GetSign<GetPercent<A>>
Better one*
type ExtractSign<A extends string> =
A extends `+${infer Rest}` ?
['+', Rest] :
A extends `-${infer Rest}` ?
['-', Rest] :
['', A]
type PercentageParser<A extends string> =
A extends `${infer Begining}%` ?
[...ExtractSign<Begining>, '%'] :
[...ExtractSign<A>, '']
Solution by maximallain #29923
type PrefixParser<A extends string> = A extends `${infer Prefix extends '+' | '-'}${infer Rest extends string}` ? [Prefix, Rest] : ['', A]
type SuffixParser<A extends string> = A extends `${infer Rest extends string}%` ? [Rest, '%'] : [A, '']
type PercentageParser<A extends string> = [PrefixParser<A>[0], ...SuffixParser<PrefixParser<A>[1]>]
Solution by normacdylan #29630
全是if/else
type PString1 = '+85%';
type PString2 = '85%';
type PString3 = '85';
type PercentageParser<T extends string> = T extends `${infer A}${infer B}` ?
A extends '-' | '+' ?
B extends `${infer E}%`?
[A, E, '%']:
[A, B, '']:
`${A}${B}` extends `${infer R}%`?
['', R, '%']:
['', `${A}${B}`, '']:
['', '', ''];
type RR1 = PercentageParser<PString3>;
Solution by sundial-dreams #29477
// your answers
type ParseSign<T extends string> =
T extends `${infer Sign extends '+' | '-'}${string}`
? Sign
: ''
type ParsePercent<T extends string> =
T extends `${string}${infer Percent extends '%'}`
? Percent
: ''
type ParseNum<T extends string> =
T extends `${ParseSign<T>}${infer Num}${ParsePercent<T>}`
? Num
: ''
type PercentageParser<A extends string> = [
ParseSign<A>,
ParseNum<A>,
ParsePercent<A>
]
Solution by ChengYaoYan #29432
type FindPlusOrMinus<S> = S extends `${infer P}${string}` ? (P extends "+" | "-" ? P : "") : ""
type FindNumber<S> = S extends `${"+" | "-"}${infer Number}${"%"}`
? Number
: S extends `${""}${infer Number}${"%"}`
? Number
: S extends `${"+" | "-"}${infer Number}${""}`
? Number
: S extends `${""}${infer Number}${""}`
? Number
: "";
type FindPercent<S> = S extends "%" ? S : S extends `${string}${infer P}` ? (P extends "%" ? P : FindPercent<P>) : ""
type PercentageParser<A extends string> = [FindPlusOrMinus<A>, FindNumber<A>, FindPercent<A>]
Solution by hajeonghun #28824
type CheckPrefix${infer Num}%
? [Num, "%"] : [T, ""];
type PercentageParser = A extends `${CheckPrefix<
infer Prefix
}${infer R}` ? [Prefix, ...CheckSuffix
] : ["", ...CheckSuffix];
Solution by DoubleWoodLin #28659
type Operator = "+" | "-";
type Percent = "%";
type DropPercent<S extends string> = S extends `${infer N}${Percent}` ? N : S;
type DropOperator<S extends string> = S extends `${Operator}${infer N}` ? N : S;
type OperateParser<S extends string> = S extends `${infer O}${string}`
? O extends Operator
? O
: ""
: "";
type PercentParser<S extends string> = S extends `${string}${Percent}`
? Percent
: "";
type PercentageParser<S extends string> = [
OperateParser<S>,
DropPercent<DropOperator<S>>,
PercentParser<S>
];
Solution by DoGukKim #28337
// your answers
type PercentageParser<A extends string, T extends string [] = ['', '', '']> = A extends ''
? T
: A extends `${infer F}${infer R}`
? F extends '%'
? PercentageParser<R, [`${T[0]}`, `${T[1]}`, `${T[2]}${F}`]>
: F extends '+' | '-'
? PercentageParser<R, [`${T[0]}${F}`, `${T[1]}`, `${T[2]}`]>
: PercentageParser<R, [`${T[0]}`, `${T[1]}${F}`, `${T[2]}`]>
// 一个 % + -
: A extends '%'
? PercentageParser<'', [`${T[0]}`, `${T[1]}`, `${T[2]}${A}`]>
: A extends '+' | '-'
? PercentageParser<'', [`${T[0]}${A}`, `${T[1]}`, ``]>
: PercentageParser<'', T>
Solution by ixiaolong2023 #27787