Skip to content

Instantly share code, notes, and snippets.

@burtek
Created December 26, 2021 21:27
Show Gist options
  • Save burtek/c8a27fc2f11a3c307416f1c6a77ec137 to your computer and use it in GitHub Desktop.
Save burtek/c8a27fc2f11a3c307416f1c6a77ec137 to your computer and use it in GitHub Desktop.
TS printf PoC
const formatters = {
d(arg: number): string { return `${arg}` },
s(arg: string): string { return arg },
j(arg: Record<string, any>): string { return JSON.stringify(arg) },
I(arg: Date): string { return arg.toISOString() }
}
type TypeMark = {
[K in keyof typeof formatters]: Parameters<typeof formatters[K]>[0]
}
type MatchBeginning<R extends string, T extends `%${keyof TypeMark}${R}`> = T extends `%${infer TM}${R}`
? TM extends keyof TypeMark
? [TypeMark[TM], ...ArgTypes<R>]
: ArgTypes<R>
: ArgTypes<R>
type ArgTypes<T extends string> = T extends ''
? []
: T extends `%${keyof TypeMark}${infer rest}`
? T extends `%${infer TM}${rest}`
? TM extends keyof TypeMark
? [TypeMark[TM], ...ArgTypes<rest>]
: ArgTypes<rest>
: ArgTypes<rest>
: T extends `${infer _}%${infer rest}`
? ArgTypes<`%${rest}`>
: []
type A = ArgTypes<'c%s,dupa%d%s'>;
type B = ArgTypes<'%s,dupa%d%s'>;
const isFormatter = (key: string): key is keyof typeof formatters => typeof (formatters as any)[key] === 'function'
function printf<T extends string>(format: T, ...args: ArgTypes<T>): string {
let currArg = -1;
let lastFound = -1;
let text = format as string;
while (currArg + 1 < args.length) {
lastFound = text.indexOf('%', lastFound) + 1;
if(!lastFound) return text;
const formatterType = text[lastFound]
if (isFormatter(formatterType)) {
const pre = text.substring(0, lastFound - 1);
const formatted = formatters[formatterType](args[++currArg]);
const rest = text.substring(lastFound + 1);
text = `${pre}${formatted}${rest}`;
lastFound = pre.length + formatted.length;
}
}
return text;
}
const a = printf('c%s,dupa%d%j%I', 'ssss%s', 1, { a: 1 }, new Date());
const b = printf('%s,dupa%d%s', 's', 1, 's');
console.log(a, b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment