Skip to content

Instantly share code, notes, and snippets.

@JonDotsoy
Last active April 5, 2024 14:24
Show Gist options
  • Save JonDotsoy/978d48fda921fa8c7f4f058c4dbf2da5 to your computer and use it in GitHub Desktop.
Save JonDotsoy/978d48fda921fa8c7f4f058c4dbf2da5 to your computer and use it in GitHub Desktop.
unindent to typescript
expect(
unindent`
Ok
`,
).toEqual("Ok\n");
expect(
unindent`
foo
biz
`,
).toEqual("foo\n biz\n");
expect(
unindent(2)`
foo
biz
`,
).toEqual(" foo\n biz\n");
type UnindentParamsStringRaw = Parameters<typeof String.raw>;
type UnindentParamsIndentSize = [indentSize: number];
type UnindentParams = UnindentParamsStringRaw | UnindentParamsIndentSize;
const isUnindentParamsIndentSize = (
params: unknown,
): params is UnindentParamsIndentSize =>
typeof params === "object" &&
Array.isArray(params) &&
typeof params[0] === "number";
const isUnindentParamsStringRaw = (
params: unknown,
): params is UnindentParamsStringRaw =>
typeof params === "object" &&
Array.isArray(params) &&
typeof params[0] === "object" &&
typeof params[0].raw === "object" &&
Array.isArray(params[0].raw);
const unindentTemplate = (indentSize: number, template: string) =>
template
.split("\n")
.splice(1)
.map((line) => line.substring(indentSize))
.join("\n");
const getIndentSize = (template: string) =>
/\n(?<indent>\s+)/.exec(template)?.groups?.indent.length ?? 0;
type ResponseRendered = string;
type ResponseRender = (...params: UnindentParamsStringRaw) => ResponseRendered;
type R<T extends UnindentParams> = T extends UnindentParamsIndentSize
? ResponseRender
: ResponseRendered;
export const unindent = <T extends UnindentParams>(...params: T): R<T> => {
const paramsUnknown: unknown = params;
if (isUnindentParamsIndentSize(paramsUnknown)) {
const indentSize = paramsUnknown[0];
const render: ResponseRender = (...params) =>
unindentTemplate(indentSize, String.raw(...params));
return render as any;
}
if (isUnindentParamsStringRaw(paramsUnknown)) {
const template = String.raw(...paramsUnknown);
const indentSize = getIndentSize(template);
const rendered: ResponseRendered = unindentTemplate(indentSize, template);
return rendered as any;
}
throw new Error("Invalid params");
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment