type ParsePrintFormat<S extends string> = S extends `${string}%${infer F}${infer rest}` ? (F extends keyof ControlsMap ? [ControlsMap[F], ...ParsePrintFormat<rest>] : ParsePrintFormat<rest>) : []
Solution by ouzexi #34217
type ControlsMap = {
c: "char";
s: "string";
d: "dec";
o: "oct";
h: "hex";
f: "float";
p: "pointer";
};
type ParsePrintFormat<S extends string> =
S extends `${string}%${infer S}${infer Rest}`
? S extends keyof ControlsMap
? [ControlsMap[S], ...ParsePrintFormat<Rest>]
: ParsePrintFormat<Rest>
: [];
Solution by Vampirelee #32608
If I have understood correct the task is not adopted to TS language. So this is my solution for TS types (can be expanded for more symbols and types):
type ControlsMap = {
s: string,
d: number,
}
type Search<
M extends string
> = M extends `${string}%${infer C extends keyof ControlsMap}${string}` ? ControlsMap[C] : never
type Loop<
M extends string,
P extends any[] = [],
> =
M extends `${string}%${keyof ControlsMap}${infer E extends string}` ?
E extends `${string}%${keyof ControlsMap}${string}` ? Loop<E, [...P, Search<M>]> :
[...P, Search<M>]
: never;
declare function printf<M extends string>(
message: M,
...args: Loop<M>,
): void;
// Some tests
printf("The result is %d.", 42); // Success
printf("The result is %d.", 'text'); // Error
printf("The result is %d %s.", 'text'); // Error
printf("The result is %s.", 'text'); // Success
printf("The result is %s %d.", 42); // Error
printf2("The result is %s %d.", 'text', 42); // Success
Solution by alexbidenko #32562
type ControlsMap = {
c: 'char';
s: 'string';
d: 'dec';
o: 'oct';
h: 'hex';
f: 'float';
p: 'pointer';
};
type ParsePrintFormat<S extends string, R extends unknown[] = []> = S extends `${string}%${infer L}${infer LL}`
? L extends keyof ControlsMap
? ParsePrintFormat<`${LL}`, [...R, ControlsMap[L]]>
: ParsePrintFormat<`${LL}`, [...R]>
: R;
Solution by leejaehyup #31987
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type ParsePrintFormat<S extends string> = S extends `${string}%${infer L}${infer R}`
? L extends keyof ControlsMap
? [ControlsMap[L], ...ParsePrintFormat<R>]
: ParsePrintFormat<R>
: []
Solution by smileboyi #27494
// your answers
type ParsePrintFormat<S extends String, Res extends unknown[] = []> =
S extends `${infer X}%${infer Y}${infer Z}`
? Y extends keyof ControlsMap
? ParsePrintFormat<Z, [...Res, ControlsMap[Y]]>
: ParsePrintFormat<Z, Res>
: Res
Solution by kiki-zjq #26052
type ParsePrintFormat<T extends string> = T extends `${infer _}%${infer R1}`
? R1 extends `${infer F}${infer R2}`
? F extends keyof ControlsMap
? [ControlsMap[F], ...ParsePrintFormat<R2>]
: ParsePrintFormat<R2>
: []
: [];
Solution by JohnLi1999 #25341
// your answers
type ParsePrintFormat<T extends string, Res extends string[] = [], Flag extends boolean = false> =
T extends `${infer Left}${infer Rest}`
? Left extends '%'
? Flag extends false
? ParsePrintFormat<Rest, Res, true>
: ParsePrintFormat<Rest, Res, false>
: Flag extends true
? Left extends keyof ControlsMap
? ParsePrintFormat<Rest, [...Res, ControlsMap[Left]], false>
: ParsePrintFormat<Rest, Res, false>
: ParsePrintFormat<Rest, Res, false>
: Res
Solution by studymachiney #25095
type SymbolCountType = 'odd' | 'even';
type ParsePrintFormat<T extends string, PrefixCount extends SymbolCountType = 'odd', R extends string[] = []> = T extends `${infer A} %${infer B}` ? HasMultiIdentifiers<T> extends true ? HandleMultiId<T, PrefixCount> : MatchPlaceholder<B, PrefixCount, [...R]> : [];
type HasMultiIdentifiers<M extends string> = M extends `${infer A} %${infer B} %${infer C}` ? true : false;
type HandleMultiId<H extends string, PrefixCount extends SymbolCountType = 'odd', R extends string[] = []> = H extends `${infer A} %${infer B} %${infer C}` ? HandleMultiId<C, PrefixCount, [...R, ...MatchPlaceholder<B, PrefixCount, []>]> : MatchPlaceholder<H, PrefixCount, [...R]>;
// type EndsWithDot<M extends string> = M extends `${infer C}.` ? true : false;
// type EndsWithColon<M extends string> = M extends `${infer C}:` ? true : false;
type GetValue<K extends string, Type extends SymbolCountType, R extends string[] = []> = Type extends 'odd' ? K extends keyof ControlsMap ? [...R, ControlsMap[K]] : [] : [];
// 1. multiple %; 2. ends with width dot; 3. nil value; 4. multi placeholder indentifier
type MatchPlaceholder<U, L extends SymbolCountType = 'odd', R extends string[] = []> = U extends `%${infer A}` ? L extends 'odd' ? MatchPlaceholder<A, 'even', [...R]> : MatchPlaceholder<A, 'odd', [...R]> : U extends `${infer B}.` ? GetValue<B, L, R> : U extends `${infer S}:${infer N}` ? GetValue<S, L, R> : U extends string ? GetValue<U, L, R> : [];
Solution by yolilufei #24705
type ParsePrintFormat<T extends string> = T extends `${any}%${infer S}${infer R}` ?
(S extends keyof ControlsMap ? [ControlsMap[S], ...ParsePrintFormat<R>] : ParsePrintFormat<R>) :
[];
Solution by E-uler #24692
type ParsePrintFormat<T extends string, Acc extends unknown[] = []> = T extends `${string}%${infer Letter}${infer Rest}`
? Letter extends keyof ControlsMap
? ParsePrintFormat<Rest, [...Acc, ControlsMap[`${Letter}`]]>
: ParsePrintFormat<Rest, Acc>
: Acc
Solution by NeylonR #24443
type ParsePrintFormat<PrintFS, Res extends string[] = []> =
PrintFS extends `%${infer F extends keyof ControlsMap}${infer R}`
? ParsePrintFormat<R, [...Res, ControlsMap[F]]>
: PrintFS extends `%%${infer R}`
? ParsePrintFormat<R, Res>
: PrintFS extends `${string}${infer R}`
? ParsePrintFormat<R, Res>
: Res
Solution by flavianh #24363
// your answers
type Char = keyof ControlsMap
type ParsePrintFormat<S extends string,Result extends string[]= []> = S extends `${infer L}%${infer C}${infer R}`
? C extends Char
? ParsePrintFormat<R,[...Result,ControlsMap[C]]>
: ParsePrintFormat<R,Result>
:Result
Solution by walker-hzx #24302
type ParsePrintFormat<S extends string, R extends string[] = []> = S extends `${infer H}%${infer C}${infer T}` ? C extends keyof ControlsMap ? ParsePrintFormat<T, [...R, ControlsMap[C]]> : ParsePrintFormat<T, R> : R
Solution by sabercc #24216
type ParsePrintFormat<
S extends string,
U extends any[] = []
> = S extends `${infer Other}%${infer F}${infer R}`
? F extends keyof ControlsMap
? ParsePrintFormat<R, [...U, ControlsMap[F]]>
: ParsePrintFormat<R, U>
: U;
Solution by coderyoo1 #23018
// your answers
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type ParsePrintFormat<
T,
Acc extends unknown[] = []
> = T extends `${infer A}%${infer C}${infer D}`
? C extends keyof ControlsMap
? [...Acc, ControlsMap[C], ...ParsePrintFormat<D, Acc>]
: [...Acc, ...ParsePrintFormat<D, Acc>]
: Acc
Solution by jxhhdx #22823
interface ControlsMap {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type ParsePrintFormat<S extends string, V extends unknown[] = []> =
S extends `${infer L}%${infer P}${infer R}`
? P extends keyof ControlsMap
? ParsePrintFormat<`${L}${R}`, [...V, ControlsMap[P]]>
: ParsePrintFormat<`${L}${R}`, V>
: V
Solution by drylint #22212
// your answers
type ParsePrintFormat<T extends string, R extends string[] = [], G extends boolean = false> =
T extends `${infer First}${infer Rest}`
? G extends true
? First extends keyof ControlsMap
? ParsePrintFormat<Rest, [...R, ControlsMap[First]], false>
: First extends '%' ? ParsePrintFormat<Rest, R, false> : ParsePrintFormat<Rest, R, false>
: First extends '%' ? ParsePrintFormat<Rest, R, true> : ParsePrintFormat<Rest, R, false>
: R
Solution by 437204933 #22049
type ParsePrintFormat<S extends string> = S extends `${string}%${infer C}${infer Rest}` ?
[...(C extends keyof ControlsMap ? [ControlsMap[C]] : []), ...ParsePrintFormat<Rest>] : [];
Solution by Karamuto #21950
type ParsePrintFormat<S extends string> =
S extends `${any}%${infer K}${infer R}`
? [...(K extends keyof ControlsMap ? [ControlsMap[K]] : []), ...ParsePrintFormat<R>]
: [];
Solution by ivbrajkovic #21637
ype ParsePrintFormat<T,Result extends Array<string> = []> =
T extends `${infer A}%${infer B}${infer C}` ?
B extends keyof ControlsMap ?
ParsePrintFormat<C,[...Result,ControlsMap[B]]> :
ParsePrintFormat<C,Result> :
Result```
Solution by so11y #21097
type ParsePrintFormat<S extends string> = S extends `${string}%${infer TControl extends keyof ControlsMap}${infer TRight}`
? [ControlsMap[TControl], ...ParsePrintFormat<TRight>]
: S extends `${string}%${string}${infer TRight}` ? ParsePrintFormat<TRight>
: [];
Solution by mdakram28 #20644
// your answers
type RemoveSymbol<S extends string> = S extends `%${infer R}` ? R : S
type ParsePrintFormat<S> = S extends `${infer F} %${infer P extends keyof ControlsMap}${infer Sybmol}${infer Rest}`
? [...[ControlsMap[P],...ParsePrintFormat<Rest>]] :
S extends `${infer G} %${infer H}.`
? ParsePrintFormat<`${G} ${RemoveSymbol<H>}.`> : []
Solution by YqxLzx #20518
type ParsePrintFormat<T extends string> = T extends `${string}%${infer K}${infer O}`
? K extends keyof ControlsMap
? [ControlsMap[K], ...ParsePrintFormat<O>]
: ParsePrintFormat<O>
: []
Solution by pengzhanbo #20510
// your answers
// 1. 找出以 % 开头的特殊字符,调用 HandlerChar 进行处理;
// - 需要考虑 %开头的字符是否是适用的,既偶数%是不需要做处理(不需要从 controlMap中取结果),奇数%是需要进行处理的。用 Last 字段来进行判断,当前Char 与 LastChar 都是 % 需要对对碰,清空,将Last变为 ‘’继续递归处理 str 直到 当前字符为 ControlMap 的 key并且Last 为 % 表明是我们想要的结果
// 将结果和 剩余字符串以数组的形式返回,方便后续处理;
// 2. 根据 HandlerChar 返回的结果,只有在是数组的情况才是我们需要保存的,字符串的话需要继续递归调用 FindSpChar
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type HandleChar<C extends string,Last extends string = '', Ret extends string[] = []> = C extends `${infer First}${infer Rest}` ?First extends '%' ? Last extends '%' ? HandleChar<Rest,'',Ret>: HandleChar<Rest, '%', Ret> : First extends keyof ControlsMap ? Last extends '%' ? [ControlsMap[First],Rest] : Rest : Rest : ''
type FindSpChar<S extends string, Ret extends string[] = []>= S extends `${infer Header}%${infer Rest}` ? HandleChar<`%${Rest}`> extends infer HRes ? HRes extends any[] ? FindSpChar<HRes[1],[...Ret,HRes[0]]>:HRes extends string ? FindSpChar<HRes,Ret>: never : never: Ret
type res = FindSpChar<`%%%d..`>
type ParsePrintFormat<S extends string> = FindSpChar<S>
Solution by Rebornjiang #20481
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type AllowedLetters = keyof ControlsMap
type AllowedValues = ControlsMap[AllowedLetters]
type ParsePrintFormat<S extends string, Acc extends AllowedValues[] = []> =
S extends `${any}%${infer Letter}${infer Rest}`
? Letter extends AllowedLetters
? ParsePrintFormat<Rest, [...Acc, ControlsMap[Letter]]>
: ParsePrintFormat<Rest, Acc>
: Acc
Solution by zhaoyao91 #20443
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type ParsePrintFormat<S extends string> = S extends `${string}%${infer A}`
? A extends `${infer F}${infer B}`
? F extends keyof ControlsMap
? [ControlsMap[F], ...ParsePrintFormat<B>]
: ParsePrintFormat<B>
: []
: []
Solution by theoolee #19575
type ControlsMap = {
c: 'char';
s: 'string';
d: 'dec';
o: 'oct';
h: 'hex';
f: 'float';
p: 'pointer';
};
type ParsePrintFormat<S extends string, Result extends string[] = []> = S extends `${infer F}${infer M}${infer R}`
? F extends '%'
? M extends keyof ControlsMap
? ParsePrintFormat<R, [...Result, ControlsMap[M]]>
: ParsePrintFormat<R, Result>
: ParsePrintFormat<`${M}${R}`, Result>
: Result;
Solution by CaoXueLiang #19026
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
}
type ParsePrintFormat<T> = T extends `${infer L}${infer M}${infer R}`
? L extends '%'
? M extends keyof ControlsMap
? [ControlsMap[M], ...ParsePrintFormat<`${R}`>]
: ParsePrintFormat<`${R}`>
: ParsePrintFormat<`${M}${R}`>
: []
Solution by milletlovemouse #18497
type ControlsMap = {
c: 'char'
s: 'string'
d: 'dec'
o: 'oct'
h: 'hex'
f: 'float'
p: 'pointer'
};
type ParsePrintFormat<
S extends string,
Result extends string[] = [],
Cnt extends 0[] = []
> = S extends `${infer F}${infer R}` ?
F extends '%' ?
ParsePrintFormat<R, Result, Cnt['length'] extends 2 ? [0] : [...Cnt, 0]> :
Cnt['length'] extends 1 ?
ParsePrintFormat<R, F extends keyof ControlsMap ? [...Result, ControlsMap[F]] : Result, []> :
ParsePrintFormat<R, Result, []> :
Result;
Solution by CallMeSaltyF1sh #18284