Reducing Boilerplate with TagExt for TypeScript
How do we feel about this for reducing some boilerplate for tags?
With the impl of TagExt looking like this:
type Foo = Readonly<{
make: () => 'foo';
}>;
const Foo = TagExt.make<Foo>('@api/foo');
// ^? Context.TagClass<symbol, string, Readonly<{
// make: () => 'foo';
// }>>type Foo = Readonly<{
make: () => 'foo';
}>;
const Foo = TagExt.make<Foo>('@api/foo');
// ^? Context.TagClass<symbol, string, Readonly<{
// make: () => 'foo';
// }>>With the impl of TagExt looking like this:
declare const RequiredTypeArgumentSymbol: unique symbol;
function make<T = typeof RequiredTypeArgumentSymbol>(
name: string,
..._: T extends typeof RequiredTypeArgumentSymbol
? ['Type argument is required', never]
: []
): Context.TagClass<symbol, string, T> {
const typeId: symbol = Symbol.for(name);
return Context.Tag(name)<typeof typeId, T>();
}
export const TagExt = {
make,
};declare const RequiredTypeArgumentSymbol: unique symbol;
function make<T = typeof RequiredTypeArgumentSymbol>(
name: string,
..._: T extends typeof RequiredTypeArgumentSymbol
? ['Type argument is required', never]
: []
): Context.TagClass<symbol, string, T> {
const typeId: symbol = Symbol.for(name);
return Context.Tag(name)<typeof typeId, T>();
}
export const TagExt = {
make,
};