@anireact/d
Version:
Dedent templates, autoindent interpolations, and more.
213 lines • 6.15 kB
text/typescript
/**
* Just an identity function. Can be reused to save few bytes of your bundle, huh.
*/
export declare const id: <t extends unknown>(x: t) => t;
/**
* Template tag args type check. Does its best to detect actual template-tag
* calls and to filter out other similar signatures:
*
* - The {@linkcode args} array must be non-empty.
* - The head `args[0]`:
* - Must be `Array.isArray`.
* - Must be frozen.
* - Must have own `raw` prop with non-enumerable `value` descriptor.
* - The raws `args[0].raw`:
* - Must be `Array.isArray`.
* - Must be frozen.
* - Must have the same length as head.
* - The tail `args.slice(1)`:
* - Must be one item shorter than head.
*
* ```typescript
* function f(...args: BDD.Args<any> | [x: string[]]) {
* if (isTemplate(args)) {
* // Called as a tag
* } else {
* let [x] = args;
* // Called as a regular function
* }
* }
* ```
*/
export declare const isTemplate: <t extends d.Args<any>>(args: any[]) => args is t;
/**
* The dedent tag you want:
*
* - Raw mode.
* - If the first line is blank, it’s trimmed.
* - If the last line is blank, it’s trimmed.
* - Other lines are dedented by the least common indent.
* - Blank lines don’t affect the dedent width.
* - Non-blank first line doesn’t affect the dedent width and isn’t dedented.
* - Tab interpreted as a _single_ space.
* - Interpolation values are converted to strings.
* - If the interpolation value is multiline, the lines are autoindented to
* match the indent of the line the interpolation is placed at. Blank lines of
* interpolation are not autoindented.
* - Completebly blank templates with no interpolations are kept untouched.
*
* _See README or tests for additional examples._
*/
export declare function d(...args: d.Args<any>): string;
/**
* Custom dedent tag constructor.
*
* _See the types {@linkcode d.Tag|Tag} and {@linkcode d.Params|Params}._
*
* ```typescript
* // Similar to `d`, but uses cooked literals:
* d({
* raw: false,
* impl: d,
* });
*
* // Similar to `d`, but doesn’t autoindent interpolations:
* d({
* impl: v => v.map(d.stringify).join(''),
* });
*
* // Similar to `d`, but doesn’t concatenate substrings:
* d({
* impl: v => v.map(d),
* });
*
* // Similar to `d.tokenize`, but stringifies tokens:
* d({
* impl: v => v.map(d.stringify),
* });
* ```
*
* @param params Tag constructor params.
* @returns Constructed dedent tag.
*/
export declare function d<q, z>(params: d.Params<q, z>): d.Tag<q, z>;
/**
* The default {@linkcode d} tag {@linkcode d.Params.impl|impl} function:
*
* 1. Stringifies tokens and autoindents interpolations.
* 2. Then concatentates everything into a single string.
*/
export declare function d(v: d.Token<any>[]): string;
/**
* Converts {@linkcode d.Token|Token} to string, autoindents interpolations:
*
* ```typescript
* let arr = [
* { lit: true, value: 'lit-1' },
* { lit: false, value: 'line-1\nline-2', pad: ' ' },
* { lit: true, value: 'lit-2' },
* ];
*
* deepEqual(arr.map(d), [
* 'lit-1',
* 'line-1\n line-2',
* 'lit-2',
* ]);
* ```
*
* @param t A token to autoindent.
* @returns Stringified and autoindented token value.
*/
export declare function d(t: d.Token<any>): string;
export declare namespace d {
/**
* Template tag args array type.
*
* @template q Quasi type.
*/
type Args<q> = [head: TemplateStringsArray, ...tail: q[]];
/**
* Template tag type.
*
* @template q Quasi type.
* @template z Result type.
*/
type Tag<q, z> = (...args: Args<q>) => z;
/**
* Better Dedent token type, either literal {@linkcode Lit} or interpolation
* {@linkcode Quasi}.
*/
type Token<q> = Lit | Quasi<q>;
/**
* Literal token.
*/
interface Lit {
/** Type tag. */ readonly lit: true;
/** Literal value. */ value: string;
}
/**
* Quasi token.
*
* @template q Quasi type.
*/
interface Quasi<q> {
/** Type tag. */ readonly lit: false;
/** Quasi value. */ value: q;
/** Autoindent prefix. */ pad: string;
}
/**
* Custom Better Dedent tag {@link d|constructor} params.
*
* @template q Quasi type.
* @template z Result type.
*/
interface Params<q, z> {
/** Raw mode flag; defaults to `true`. */ raw?: boolean | undefined;
/** Tag implementation function. */ impl(v: Token<q>[]): z;
}
/**
* Converts {@linkcode Token} value using `String()`.
*
* ```typescript
* d.stringify({
* lit: true,
* value: 'Literal',
* }) === 'Literal';
*
* d.stringify({
* lit: false,
* value: 2434,
* pad: '',
* }) === '2434';
*
* d.stringify({
* lit: false,
* value: {
* toString: () => 'x.toString',
* },
* pad: '',
* }) === 'x.toString';
*
* d.stringify({
* lit: false,
* value: {
* [Symbol.toPrimitive]: () => 'x[Symbol.toPrimitive]',
* },
* pad: '',
* }) === 'x[Symbol.toPrimitive]';
* ```
*/
const stringify: (t: d.Token<any>) => string;
/**
* Similar to the {@linkcode d} tag, but returns an array of
* {@linkcode Token} objects, with no autoindent applied to interpolation
* tokens:
*
* ```typescript
* deepEqual(
* d.tokenize`¶
* ␣␣␣␣␣␣␣␣Literal¶
* ␣␣␣␣␣␣␣␣␣␣␣␣${'Interpolation'}¶
* ␣␣␣␣␣␣␣␣Another literal¶
* ␣␣␣␣`,
* [
* { lit: true, value: 'Literal\n ' },
* { lit: false, value: 'Interpolation', pad: ' ' },
* { lit: true, value: '\nAnother literal' },
* ],
* );
* ```
*/
const tokenize: <q extends unknown>(head: TemplateStringsArray, ...tail: q[]) => Token<q>[];
}
//# sourceMappingURL=dedent.d.mts.map