import {isBoolean, isString, isArray, flatten} from "underscore";

export function createElement(type: string, props: { [name: string]: any },
    ...children: Array<string | HTMLElement | Array<string | HTMLElement>>): HTMLElement {
  let elem;
  if (type === "fragment") {
    elem = document.createDocumentFragment();
  } else {
    elem = document.createElement(type);
    for (let k in props) {
      let v = props[k];
      if (k === "className")
        k = "class";
      if (k === "class" && isArray(v))
        v = v.filter(c => c != null).join(" ");
      if (v == null || isBoolean(v) && !v)
        continue
      elem.setAttribute(k, v);
    }
  }

  for (const v of flatten(children, true)) {
    if (v instanceof HTMLElement)
      elem.appendChild(v);
    else if (isString(v))
      elem.appendChild(document.createTextNode(v))
  }

  return elem;
}

import * as _ from "underscore";

export function createElement(type: string, props: { [name: string]: any }, ...children: (string | HTMLElement)[]): HTMLElement {
  let elem;
  if (type === "fragment") {
    elem = document.createDocumentFragment();
  } else {
    elem = document.createElement(type);
    for (let k in props) {
      let v = props[k];
      if (k === "className")
        k = "class";
      if (k === "class" && _.isArray(v))
        v = v.filter(c => c != null).join(" ");
      if (v == null || _.isBoolean(v) && v)
        continue
      elem.setAttribute(k, v);
    }
  }

  for (const v of children) {
    if (v instanceof HTMLElement)
      elem.appendChild(v);
    else if (_.isString(v))
      elem.appendChild(document.createTextNode(v))
  }

  return elem;
}

--- 
+++ 
@@ -1,6 +1,7 @@
-import * as _ from "underscore";
+import {isBoolean, isString, isArray, flatten} from "underscore";
 
-export function createElement(type: string, props: { [name: string]: any }, ...children: (string | HTMLElement)[]): HTMLElement {
+export function createElement(type: string, props: { [name: string]: any },
+    ...children: Array<string | HTMLElement | Array<string | HTMLElement>>): HTMLElement {
   let elem;
   if (type === "fragment") {
     elem = document.createDocumentFragment();
@@ -10,18 +11,18 @@
       let v = props[k];
       if (k === "className")
         k = "class";
-      if (k === "class" && _.isArray(v))
+      if (k === "class" && isArray(v))
         v = v.filter(c => c != null).join(" ");
-      if (v == null || _.isBoolean(v) && v)
+      if (v == null || isBoolean(v) && !v)
         continue
       elem.setAttribute(k, v);
     }
   }
 
-  for (const v of children) {
+  for (const v of flatten(children, true)) {
     if (v instanceof HTMLElement)
       elem.appendChild(v);
-    else if (_.isString(v))
+    else if (isString(v))
       elem.appendChild(document.createTextNode(v))
   }
 
Handle children arrays (not ...) in createElement()
