typelit
Version:
A type-safe string templating library for TypeScript
34 lines (32 loc) • 1.8 kB
TypeScript
type Nested<Names extends string[], T> = Names extends [
infer Head extends string
] ? {
[K in Head]: T;
} : Names extends [infer Head extends string, ...infer Rest extends string[]] ? {
[K in Head]: Nested<Rest, T>;
} : never;
type Var<Names extends string[], T> = {
_extract: (ctx: Nested<Names, T>) => T;
stringify: (value: T) => string;
};
type VarName<T> = T extends Var<infer VN, infer _VT> ? VN[0] : never;
type VarType<T extends Var<string[], any>> = T extends Var<infer VN, infer VT> ? VN extends [infer _Head extends string] ? VT : VN extends [infer _Head extends string, ...infer Rest extends string[]] ? Nested<Rest, VT> : never : never;
type VarList = Var<string[], any>[];
type UnionToIntersection<U> = (U extends object ? (k: U) => void : U) extends (k: infer I) => void ? I : U;
type Prettify<T> = {
[K in keyof T]: T[K] extends Context<infer _Vars> ? Prettify<T[K]> : T[K];
} & {};
type Context<Vars extends VarList> = Prettify<{
[K in Vars[number] as VarName<K>]: UnionToIntersection<VarType<K>>;
}>;
type TemplateFn<Vars extends VarList> = (ctx: Context<Vars>) => string;
declare function typelit<Vars extends VarList>(strings: TemplateStringsArray, ...vars: Vars): TemplateFn<Vars>;
declare namespace typelit {
var boolean: <Names extends string[]>(...names: Names) => Var<Names, boolean>;
var string: <Names extends string[]>(...names: Names) => Var<Names, string>;
var number: <Names extends string[]>(...names: Names) => Var<Names, number>;
var bigint: <Names extends string[]>(...names: Names) => Var<Names, bigint>;
var date: <Names extends string[]>(...names: Names) => Var<Names, Date>;
var json: <Names extends string[]>(...names: Names) => Var<Names, any>;
}
export { type TemplateFn, type Var, typelit as default };