Сделал так:
const $ = new Proxy(() => {}, {
  apply(t, _, v) {
    return v.join("");
  },
  get(_, tag) {
    return (attrs, ...children) => {
      return (
        "<" +
        tag +
        (attrs ? " " + attrs : "") +
        (children.length ? ">" + children.join("") + "</" + tag + ">" : " />")
      );
    };
  },
});
const DOM = $(
  "Hello World",
  $.input(`value="123"`),
  "Lol",
  $.button(`id="btn"`, "Nice button", $.span(0, "the span"))
);
console.log(DOM);
Получаем:
Hello World<input value="123" />Lol<button id="btn">Nice button<span>the span</span></button>