|
@@ -2,7 +2,6 @@ import { ChildrenFlags } from './flags'
|
|
|
import {
|
|
import {
|
|
|
ComponentClass,
|
|
ComponentClass,
|
|
|
FunctionalComponent,
|
|
FunctionalComponent,
|
|
|
- Component,
|
|
|
|
|
ComponentInstance
|
|
ComponentInstance
|
|
|
} from './component'
|
|
} from './component'
|
|
|
import { ComponentOptions } from './componentOptions'
|
|
import { ComponentOptions } from './componentOptions'
|
|
@@ -14,7 +13,8 @@ import {
|
|
|
createFragment,
|
|
createFragment,
|
|
|
createPortal,
|
|
createPortal,
|
|
|
VNodeData,
|
|
VNodeData,
|
|
|
- BuiltInProps
|
|
|
|
|
|
|
+ BuiltInProps,
|
|
|
|
|
+ Key
|
|
|
} from './vdom'
|
|
} from './vdom'
|
|
|
import { isObservable } from '@vue/observer'
|
|
import { isObservable } from '@vue/observer'
|
|
|
import { warn } from './warning'
|
|
import { warn } from './warning'
|
|
@@ -22,6 +22,14 @@ import { warn } from './warning'
|
|
|
export const Fragment = Symbol()
|
|
export const Fragment = Symbol()
|
|
|
export const Portal = Symbol()
|
|
export const Portal = Symbol()
|
|
|
|
|
|
|
|
|
|
+type RawChildType = VNode | string | number | boolean | null | undefined
|
|
|
|
|
+
|
|
|
|
|
+export type RawSlots = {
|
|
|
|
|
+ [name: string]: () => RawChildrenType
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export type RawChildrenType = RawChildType | RawChildType[]
|
|
|
|
|
+
|
|
|
export type ElementType =
|
|
export type ElementType =
|
|
|
| string
|
|
| string
|
|
|
| FunctionalComponent
|
|
| FunctionalComponent
|
|
@@ -30,10 +38,6 @@ export type ElementType =
|
|
|
| typeof Fragment
|
|
| typeof Fragment
|
|
|
| typeof Portal
|
|
| typeof Portal
|
|
|
|
|
|
|
|
-type RawChildType = VNode | string | number | boolean | null | undefined
|
|
|
|
|
-
|
|
|
|
|
-export type RawChildrenType = RawChildType | RawChildType[]
|
|
|
|
|
-
|
|
|
|
|
interface VNodeFactories {
|
|
interface VNodeFactories {
|
|
|
c: typeof createComponentVNode
|
|
c: typeof createComponentVNode
|
|
|
e: typeof createElementVNode
|
|
e: typeof createElementVNode
|
|
@@ -42,20 +46,60 @@ interface VNodeFactories {
|
|
|
p: typeof createPortal
|
|
p: typeof createPortal
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-interface createElement {
|
|
|
|
|
|
|
+// This is used to differentiate the data object from
|
|
|
|
|
+// vnodes and arrays
|
|
|
|
|
+type Differ = { _isVNode?: never; [Symbol.iterator]?: never }
|
|
|
|
|
+
|
|
|
|
|
+type OptionsComponent<P> =
|
|
|
|
|
+ | (ComponentOptions<P> & { template: string })
|
|
|
|
|
+ | (ComponentOptions<P> & { render: Function })
|
|
|
|
|
+
|
|
|
|
|
+interface createElement extends VNodeFactories {
|
|
|
// element
|
|
// element
|
|
|
- (tag: string, data?: VNodeData, children?: any): VNode
|
|
|
|
|
|
|
+ (
|
|
|
|
|
+ tag: string,
|
|
|
|
|
+ // TODO support native element properties
|
|
|
|
|
+ data?: VNodeData & Differ | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
|
|
+ ): VNode
|
|
|
|
|
+ (tag: string, children?: RawChildrenType): VNode
|
|
|
|
|
+ // fragment
|
|
|
|
|
+ (
|
|
|
|
|
+ tag: typeof Fragment,
|
|
|
|
|
+ data?: ({ key?: Key } & Differ) | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
|
|
+ ): VNode
|
|
|
|
|
+ (tag: typeof Fragment, children?: RawChildrenType): VNode
|
|
|
|
|
+ // portal
|
|
|
|
|
+ (
|
|
|
|
|
+ tag: typeof Portal,
|
|
|
|
|
+ data?: ({ target: any } & BuiltInProps & Differ) | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
|
|
+ ): VNode
|
|
|
|
|
+ (tag: typeof Portal, children?: RawChildrenType): VNode
|
|
|
|
|
+ // object
|
|
|
|
|
+ <P>(
|
|
|
|
|
+ tag: OptionsComponent<P>,
|
|
|
|
|
+ data?: (P & BuiltInProps & Differ) | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
|
|
+ ): VNode
|
|
|
|
|
+ <P>(tag: OptionsComponent<P>, children?: RawChildrenType): VNode
|
|
|
// functional
|
|
// functional
|
|
|
<P>(
|
|
<P>(
|
|
|
tag: FunctionalComponent<P>,
|
|
tag: FunctionalComponent<P>,
|
|
|
- data?: P & BuiltInProps | null,
|
|
|
|
|
- children?: any
|
|
|
|
|
|
|
+ data?: (P & BuiltInProps & Differ) | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
|
|
+ ): VNode
|
|
|
|
|
+ <P>(tag: FunctionalComponent<P>, children?: RawChildrenType): VNode
|
|
|
|
|
+ // class
|
|
|
|
|
+ <P, T extends ComponentInstance<P>>(
|
|
|
|
|
+ tag: new () => T & { $props: P },
|
|
|
|
|
+ data?: (P & BuiltInProps & Differ) | null,
|
|
|
|
|
+ children?: RawChildrenType | RawSlots
|
|
|
): VNode
|
|
): VNode
|
|
|
- // stateful
|
|
|
|
|
<P, T extends ComponentInstance<P>>(
|
|
<P, T extends ComponentInstance<P>>(
|
|
|
tag: new () => T & { $props: P },
|
|
tag: new () => T & { $props: P },
|
|
|
- data?: P & BuiltInProps | null,
|
|
|
|
|
- children?: any
|
|
|
|
|
|
|
+ children?: RawChildrenType
|
|
|
): VNode
|
|
): VNode
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -138,7 +182,7 @@ export const h = ((tag: ElementType, data?: any, children?: any): VNode => {
|
|
|
ref
|
|
ref
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
-}) as createElement & VNodeFactories
|
|
|
|
|
|
|
+}) as createElement
|
|
|
|
|
|
|
|
h.c = createComponentVNode
|
|
h.c = createComponentVNode
|
|
|
h.e = createElementVNode
|
|
h.e = createElementVNode
|