1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { reduceAsync } from "https://esm.town/v/postpostscript/reduceAsync";
import type { MaybePromise } from "https://esm.town/v/postpostscript/typeUtils";
export function hybridTaggedTemplateMethod<
TResultTransformed,
TStringTransformed,
TReplacementTransformed,
TCombined,
TInitial,
>({
combine = (result: TCombined, replacement: TReplacementTransformed, string: TStringTransformed) =>
`${result}${replacement}${string}` as TCombined,
initial = (string: TStringTransformed) => {
return string as unknown as TCombined;
},
transformString = (str: string) => str as TStringTransformed,
transformReplacement = (replacement: unknown) => replacement as TReplacementTransformed,
transformResult = (result: TCombined) => result as unknown as TResultTransformed,
}: {
combine?: (result: TCombined, replacement: TReplacementTransformed, string: TStringTransformed) => TCombined;
initial?: (string: TStringTransformed) => TCombined;
transformString?: (str: string) => TStringTransformed;
transformReplacement?: (replacement: unknown) => TReplacementTransformed;
transformResult?: (result: TCombined) => TResultTransformed;
}) {
const hybridTaggedTemplate: {
(strings: TemplateStringsArray, ...replacements: unknown[]): TResultTransformed;
(string: string): TResultTransformed;
} = (strings, ...replacements) => {
if (!(strings instanceof Array)) {
return hybridTaggedTemplate([strings]);
}
const result = strings.slice(1).reduce((result, string, i) => {
const _string = transformString(string) as TStringTransformed;
const replacement = transformReplacement(replacements[i]);
return combine(result, replacement, _string);
}, initial(transformString(strings[0])));
return transformResult(result);
};
return hybridTaggedTemplate;
}
export function hybridTaggedTemplateMethodAsync<
TResultTransformed,
TStringTransformed,
TReplacementTransformed,
TCombined,
TInitial,
>({
combine = async (result: TCombined, replacement: TReplacementTransformed, string: TStringTransformed) => {
const [
_result,
_replacement,
_string,
] = await Promise.all([
result,
replacement,
string,
]);
return `${result}${_replacement}${string}` as TCombined;
},
initial = (string: TStringTransformed) => {
return string as unknown as TCombined;
},
transformString = (str: string) => str as TStringTransformed,
transformReplacement = (replacement: MaybePromise<any>) => replacement as TReplacementTransformed,
transformResult = (result: Promise<TCombined>) => result as unknown as TResultTransformed,
}: {
combine?: (result: TCombined, replacement: TReplacementTransformed, string: TStringTransformed) => TCombined;
initial?: (string: TStringTransformed) => TCombined;
transformString?: (str: string) => TStringTransformed;
transformReplacement?: (replacement: MaybePromise<any>) => TReplacementTransformed;
transformResult?: (result: Promise<TCombined>) => TResultTransformed;
}) {
const hybridTaggedTemplateAsync: {
(strings: TemplateStringsArray, ...replacements: MaybePromise<any>[]): Promise<TResultTransformed>;
(string: string): Promise<TResultTransformed>;
} = async (strings, ...replacements) => {
if (!(strings instanceof Array)) {
return hybridTaggedTemplateAsync([strings]);
}
const result = reduceAsync<TCombined, string>(strings.slice(1), async (result, string, i) => {
const _string = transformString(string);
const replacement = transformReplacement(replacements[i]);
return combine(result, replacement, _string);
}, initial(transformString(strings[0])));
return transformResult(result);
};
return hybridTaggedTemplateAsync;
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
February 28, 2024