From dde696d52e8a992a060db9e7fca64652984aa803 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Mon, 4 May 2015 13:55:19 -0500 Subject: [PATCH 1/4] Add virtual-dom type declarations, based on virtual-dom's docs.jsig --- virtual-dom/virtual-dom.d.ts | 121 +++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 virtual-dom/virtual-dom.d.ts diff --git a/virtual-dom/virtual-dom.d.ts b/virtual-dom/virtual-dom.d.ts new file mode 100644 index 000000000..70166515f --- /dev/null +++ b/virtual-dom/virtual-dom.d.ts @@ -0,0 +1,121 @@ +declare module VirtualDOM { + interface VHook { + hook(node: Element, propertyName: string): void; + unhook(node: Element, propertyName: string): void; + } + + type EventHandler = (...args: any[]) => void; + + interface VProperties { + attributes?: {[index: string]: string}; + /** + I would like to use {[index: string]: string}, but then we couldn't use an + object literal when setting the styles, since TypeScript doesn't seem to + infer that {'fontSize': string; 'fontWeight': string;} is actually quite + assignable to the type { [index: string]: string; } + */ + style?: any; + /** + The relaxation on `style` above is the reason why we need `any` as an option + on the indexer type. + */ + [index: string]: any | string | boolean | number | VHook | EventHandler | {[index: string]: string | boolean | number}; + } + + interface VNode { + tagName: string; + properties: VProperties; + children: VTree[]; + key?: string; + namespace?: string; + count: number; + hasWidgets: boolean; + hasThunks: boolean; + hooks: any[]; + descendantHooks: any[]; + version: string; + type: string; // 'VirtualNode' + } + + interface VText { + text: string; + new (text: any); + version: string; + type: string; // 'VirtualText' + } + + interface Widget { + type: string; // 'Widget' + init(): Element; + update(previous: Widget, domNode: Element): void; + destroy(node: Element): void; + } + + interface Thunk { + type: string; // 'Thunk' + vnode: VTree; + render(previous: VTree): VTree; + } + + type VTree = VText | VNode | Widget | Thunk; + + // enum VPatch { + // NONE = 0, + // VTEXT = 1, + // VNODE = 2, + // WIDGET = 3, + // PROPS = 4, + // ORDER = 5, + // INSERT = 6, + // REMOVE = 7, + // THUNK = 8 + // } + interface VPatch { + vNode: VNode, + patch: any; + new(type: number, vNode: VNode, patch: any): VPatch; + version: string; + /** + type is set to 'VirtualPatch' on the prototype, but overridden in the + constructor with a number. + */ + type: number; + } + + interface createProperties extends VProperties { + key?: string; + namespace?: string; + } + type createChildren = Array; + + /** + create() calls either document.createElement() or document.createElementNS(), + for which the common denominator is Element (not HTMLElement). + */ + function create(vnode: VText, opts?: {document?: Document, warn?: boolean}): Text; + function create(vnode: VNode | Widget | Thunk, opts?: {document?: Document, warn?: boolean}): Element; + function h(tagName: string, properties: createProperties, ...children: createChildren): VNode; + function h(tagName: string, ...children: createChildren): VNode; + function diff(left: VTree, right: VTree): VPatch[]; + /** + patch() usually just returns rootNode after doing stuff to it, so we want + to preserve that type (though it will usually be just Element). + */ + function patch(rootNode: T, patches: VPatch[], renderOptions?: any): T; +} + +declare module "virtual-dom/h" { + export = VirtualDOM.h; +} +declare module "virtual-dom/create-element" { + export = VirtualDOM.create; +} +declare module "virtual-dom/diff" { + export = VirtualDOM.diff; +} +declare module "virtual-dom/patch" { + export = VirtualDOM.patch; +} +declare module "virtual-dom" { + export = VirtualDOM; +} From 0faae8ebf7f8e4c3cab38ef35ffd4a814b811c7b Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Fri, 15 May 2015 13:00:47 -0500 Subject: [PATCH 2/4] Collapse createChildren and rename as 'VChild' --- virtual-dom/virtual-dom.d.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/virtual-dom/virtual-dom.d.ts b/virtual-dom/virtual-dom.d.ts index 70166515f..7023d38fd 100644 --- a/virtual-dom/virtual-dom.d.ts +++ b/virtual-dom/virtual-dom.d.ts @@ -86,7 +86,8 @@ declare module VirtualDOM { key?: string; namespace?: string; } - type createChildren = Array; + + type VChild = VTree[] | VTree | string[] | string; /** create() calls either document.createElement() or document.createElementNS(), @@ -94,8 +95,8 @@ declare module VirtualDOM { */ function create(vnode: VText, opts?: {document?: Document, warn?: boolean}): Text; function create(vnode: VNode | Widget | Thunk, opts?: {document?: Document, warn?: boolean}): Element; - function h(tagName: string, properties: createProperties, ...children: createChildren): VNode; - function h(tagName: string, ...children: createChildren): VNode; + function h(tagName: string, properties: createProperties, ...children: VChild[]): VNode; + function h(tagName: string, ...children: VChild[]): VNode; function diff(left: VTree, right: VTree): VPatch[]; /** patch() usually just returns rootNode after doing stuff to it, so we want From 1e2a1e22e5c44adb10667dc5bd91a2367f3af288 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Fri, 15 May 2015 13:07:19 -0500 Subject: [PATCH 3/4] Fix h() signatures to reflect virtual-hyperscript readme (I must have misread the jsig file) --- virtual-dom/virtual-dom.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virtual-dom/virtual-dom.d.ts b/virtual-dom/virtual-dom.d.ts index 7023d38fd..10575e8ca 100644 --- a/virtual-dom/virtual-dom.d.ts +++ b/virtual-dom/virtual-dom.d.ts @@ -95,8 +95,8 @@ declare module VirtualDOM { */ function create(vnode: VText, opts?: {document?: Document, warn?: boolean}): Text; function create(vnode: VNode | Widget | Thunk, opts?: {document?: Document, warn?: boolean}): Element; - function h(tagName: string, properties: createProperties, ...children: VChild[]): VNode; - function h(tagName: string, ...children: VChild[]): VNode; + function h(tagName: string, properties: createProperties, children: string | VChild[]): VNode; + function h(tagName: string, children: string | VChild[]): VNode; function diff(left: VTree, right: VTree): VPatch[]; /** patch() usually just returns rootNode after doing stuff to it, so we want From df507c636cf0c799a8a20f35af89a3d0caae6c32 Mon Sep 17 00:00:00 2001 From: Christopher Brown Date: Wed, 10 Jun 2015 12:29:45 -0500 Subject: [PATCH 4/4] Add virtual-dom tests and fix syntax to appease DT's automated checkers --- virtual-dom/virtual-dom-tests.ts | 33 ++++++++++++++++++++++++++++++++ virtual-dom/virtual-dom.d.ts | 26 +++++++++++++++++-------- 2 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 virtual-dom/virtual-dom-tests.ts diff --git a/virtual-dom/virtual-dom-tests.ts b/virtual-dom/virtual-dom-tests.ts new file mode 100644 index 000000000..98d5f1642 --- /dev/null +++ b/virtual-dom/virtual-dom-tests.ts @@ -0,0 +1,33 @@ +/// +import virtual_dom = require("virtual-dom"); +import VNode = virtual_dom.VNode; +import h = virtual_dom.h; + +function renderAny(object: any): VNode { + if (object === undefined) { + return h('i.undefined', 'undefined'); + } + else if (object === null) { + return h('b.null', 'null'); + } + else if (Array.isArray(object)) { + return h('span.array', ['[', object.map(renderAny), ']']); + } + else if (typeof object === 'object') { + var object_children = Object.keys(object).map(key => { + var child = object[key]; + return h('div', [ + h('span.key', [key, ':']), + renderAny(child), + ]); + }); + return h('div.object', object_children); + } + else if (typeof object === 'number') { + return h('span.number', object.toString()); + } + else if (typeof object === 'boolean') { + return h('span.boolean', object.toString()); + } + return h('span.string', object.toString()); +} diff --git a/virtual-dom/virtual-dom.d.ts b/virtual-dom/virtual-dom.d.ts index 10575e8ca..4902304a1 100644 --- a/virtual-dom/virtual-dom.d.ts +++ b/virtual-dom/virtual-dom.d.ts @@ -1,3 +1,8 @@ +// Type definitions for virtual-dom 2.0.1 +// Project: https://github.com/Matt-Esch/virtual-dom +// Definitions by: Christopher Brown +// Definitions: https://github.com/borisyankov/DefinitelyTyped + declare module VirtualDOM { interface VHook { hook(node: Element, propertyName: string): void; @@ -39,7 +44,7 @@ declare module VirtualDOM { interface VText { text: string; - new (text: any); + new(text: any): VText; version: string; type: string; // 'VirtualText' } @@ -71,7 +76,7 @@ declare module VirtualDOM { // THUNK = 8 // } interface VPatch { - vNode: VNode, + vNode: VNode; patch: any; new(type: number, vNode: VNode, patch: any): VPatch; version: string; @@ -93,8 +98,8 @@ declare module VirtualDOM { create() calls either document.createElement() or document.createElementNS(), for which the common denominator is Element (not HTMLElement). */ - function create(vnode: VText, opts?: {document?: Document, warn?: boolean}): Text; - function create(vnode: VNode | Widget | Thunk, opts?: {document?: Document, warn?: boolean}): Element; + function create(vnode: VText, opts?: {document?: Document; warn?: boolean}): Text; + function create(vnode: VNode | Widget | Thunk, opts?: {document?: Document; warn?: boolean}): Element; function h(tagName: string, properties: createProperties, children: string | VChild[]): VNode; function h(tagName: string, children: string | VChild[]): VNode; function diff(left: VTree, right: VTree): VPatch[]; @@ -106,16 +111,21 @@ declare module VirtualDOM { } declare module "virtual-dom/h" { - export = VirtualDOM.h; + // export = VirtualDOM.h; works just fine, but the DT checker doesn't like it + import h = VirtualDOM.h; + export = h; } declare module "virtual-dom/create-element" { - export = VirtualDOM.create; + import create = VirtualDOM.create; + export = create; } declare module "virtual-dom/diff" { - export = VirtualDOM.diff; + import diff = VirtualDOM.diff; + export = diff; } declare module "virtual-dom/patch" { - export = VirtualDOM.patch; + import patch = VirtualDOM.patch; + export = patch; } declare module "virtual-dom" { export = VirtualDOM;