]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip(types): improve h typing
authorEvan You <yyx990803@gmail.com>
Fri, 12 Oct 2018 17:42:19 +0000 (13:42 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 12 Oct 2018 17:42:19 +0000 (13:42 -0400)
packages/core/src/component.ts
packages/core/src/h.ts
packages/core/src/optional/mixin.ts [new file with mode: 0644]
packages/core/src/vdom.ts

index fcc168699b926e1cfc59149127eab32494a8b831..66fc4bb0c319a740cfebde5ddf1c2fdba8cd1853 100644 (file)
@@ -15,13 +15,13 @@ import { initializeComponentInstance } from './componentUtils'
 
 export interface ComponentClass extends ComponentClassOptions {
   options?: ComponentOptions
-  new <P extends object = {}, D extends object = {}>(): MergedComponent<P, D>
+  new <P = {}, D = {}>(): MergedComponent<P, D>
 }
 
 export type MergedComponent<P, D> = D & P & ComponentInstance<P, D>
 
 export interface FunctionalComponent<P = {}> {
-  (props: Readonly<P>, slots: Slots, attrs: Data): any
+  (props: P, slots: Slots, attrs: Data): any
   pure?: boolean
   props?: ComponentPropsOptions<P>
   displayName?: string
index 2b28ae520ed795b38e53e1974fa9d2576e58ef6e..29c7d235c0df7c8f9d0115598bfa7c91b63a0b86 100644 (file)
@@ -1,5 +1,10 @@
 import { ChildrenFlags } from './flags'
-import { ComponentClass, FunctionalComponent } from './component'
+import {
+  ComponentClass,
+  FunctionalComponent,
+  Component,
+  ComponentInstance
+} from './component'
 import { ComponentOptions } from './componentOptions'
 import {
   VNode,
@@ -7,7 +12,9 @@ import {
   createComponentVNode,
   createTextVNode,
   createFragment,
-  createPortal
+  createPortal,
+  VNodeData,
+  BuiltInProps
 } from './vdom'
 import { isObservable } from '@vue/observer'
 import { warn } from './warning'
@@ -15,7 +22,7 @@ import { warn } from './warning'
 export const Fragment = Symbol()
 export const Portal = Symbol()
 
-type ElementType =
+export type ElementType =
   | string
   | FunctionalComponent
   | ComponentClass
@@ -23,8 +30,11 @@ type ElementType =
   | typeof Fragment
   | typeof Portal
 
-export interface createElement {
-  (tag: ElementType, data?: any, children?: any): VNode
+type RawChildType = VNode | string | number | boolean | null | undefined
+
+export type RawChildrenType = RawChildType | RawChildType[]
+
+interface VNodeFactories {
   c: typeof createComponentVNode
   e: typeof createElementVNode
   t: typeof createTextVNode
@@ -32,6 +42,23 @@ export interface createElement {
   p: typeof createPortal
 }
 
+interface createElement {
+  // element
+  (tag: string, data?: VNodeData, children?: any): VNode
+  // functional
+  <P>(
+    tag: FunctionalComponent<P>,
+    data?: P & BuiltInProps | null,
+    children?: any
+  ): VNode
+  // stateful
+  <P, T extends ComponentInstance<P>>(
+    tag: new () => T & { $props: P },
+    data?: P & BuiltInProps | null,
+    children?: any
+  ): VNode
+}
+
 export const h = ((tag: ElementType, data?: any, children?: any): VNode => {
   if (
     Array.isArray(data) ||
@@ -111,7 +138,7 @@ export const h = ((tag: ElementType, data?: any, children?: any): VNode => {
       ref
     )
   }
-}) as createElement
+}) as createElement & VNodeFactories
 
 h.c = createComponentVNode
 h.e = createElementVNode
diff --git a/packages/core/src/optional/mixin.ts b/packages/core/src/optional/mixin.ts
new file mode 100644 (file)
index 0000000..902d9f2
--- /dev/null
@@ -0,0 +1,16 @@
+import { ComponentInstance, ComponentType } from '../component'
+import { ComponentOptions } from '../componentOptions'
+import { RawVNodeChildren, VNodeData } from '../vdom'
+
+export interface Mixin extends ComponentOptions {}
+
+export function applyMixins(Component: ComponentInstance, mixins: Mixin[]) {}
+
+export function h(tag: ComponentType | string, data: RawVNodeChildren): object
+export function h(
+  tag: ComponentType | string,
+  data: VNodeData,
+  children: RawVNodeChildren
+): object {
+  return {}
+}
index 0b1d948ad87621781b2c7592609d8244b4df5e67..f54fe3b136e8fc7a75a28e72ea728933aee44ffa 100644 (file)
@@ -6,6 +6,7 @@ import {
 import { VNodeFlags, ChildrenFlags } from './flags'
 import { createComponentClassFromOptions } from './componentUtils'
 import { normalizeClass, normalizeStyle, handlersRE, EMPTY_OBJ } from './utils'
+import { ElementType, RawChildrenType } from './h'
 
 // Vue core is platform agnostic, so we are not using Element for "DOM" nodes.
 export interface RenderNode {
@@ -40,21 +41,19 @@ export interface MountedVNode extends VNode {
   el: RenderNode
 }
 
-export interface VNodeData {
+export interface BuiltInProps {
   key?: Key | null
   ref?: Ref | null
-  slots?: Slots | null
-  [key: string]: any
+  slots?: RawSlots | null
 }
 
+export type VNodeData = Record<string, any> & BuiltInProps
+
 export type VNodeChildren =
   | VNode[] // ELEMENT | PORTAL
   | ComponentInstance // COMPONENT_STATEFUL
   | VNode // COMPONENT_FUNCTIONAL
   | string // TEXT
-  | null
-
-export type RawVNodeChildren = VNodeChildren | unknown[]
 
 export type Key = string | number
 
@@ -66,11 +65,15 @@ export type Slots = Readonly<{
   [name: string]: Slot
 }>
 
+export type RawSlots = {
+  [name: string]: () => RawChildrenType
+}
+
 export function createVNode(
   flags: VNodeFlags,
   tag: string | FunctionalComponent | ComponentClass | RenderNode | null,
   data: VNodeData | null,
-  children: RawVNodeChildren | null,
+  children: RawChildrenType | null,
   childFlags: ChildrenFlags,
   key: Key | null | undefined,
   ref: Ref | null | undefined,
@@ -108,7 +111,7 @@ function normalizeClassAndStyle(data: VNodeData) {
 export function createElementVNode(
   tag: string,
   data: VNodeData | null,
-  children: RawVNodeChildren | null,
+  children: RawChildrenType | null,
   childFlags: ChildrenFlags,
   key?: Key | null,
   ref?: Ref | null
@@ -123,7 +126,7 @@ export function createElementVNode(
 export function createComponentVNode(
   comp: any,
   data: VNodeData | null,
-  children: RawVNodeChildren | Slots,
+  children: RawChildrenType | Slots,
   childFlags: ChildrenFlags,
   key?: Key | null,
   ref?: Ref | null
@@ -222,7 +225,7 @@ export function createTextVNode(text: string): VNode {
 }
 
 export function createFragment(
-  children: RawVNodeChildren,
+  children: RawChildrenType,
   childFlags?: ChildrenFlags,
   key?: Key | null
 ) {
@@ -240,7 +243,7 @@ export function createFragment(
 
 export function createPortal(
   target: RenderNode | string,
-  children: RawVNodeChildren,
+  children: RawChildrenType,
   childFlags?: ChildrenFlags,
   key?: Key | null,
   ref?: Ref | null
@@ -296,7 +299,7 @@ export function cloneVNode(vnode: VNode, extraData?: VNodeData): VNode {
       flags,
       vnode.tag,
       clonedData,
-      vnode.children,
+      vnode.children as RawChildrenType,
       vnode.childFlags,
       vnode.key,
       vnode.ref,