From: Evan You Date: Fri, 12 Oct 2018 17:42:19 +0000 (-0400) Subject: wip(types): improve h typing X-Git-Tag: v3.0.0-alpha.0~1120 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47a2b25a9577b9591d1a7d02ea69fe42244beaf3;p=thirdparty%2Fvuejs%2Fcore.git wip(types): improve h typing --- diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index fcc168699b..66fc4bb0c3 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -15,13 +15,13 @@ import { initializeComponentInstance } from './componentUtils' export interface ComponentClass extends ComponentClassOptions { options?: ComponentOptions - new

(): MergedComponent + new

(): MergedComponent } export type MergedComponent = D & P & ComponentInstance export interface FunctionalComponent

{ - (props: Readonly

, slots: Slots, attrs: Data): any + (props: P, slots: Slots, attrs: Data): any pure?: boolean props?: ComponentPropsOptions

displayName?: string diff --git a/packages/core/src/h.ts b/packages/core/src/h.ts index 2b28ae520e..29c7d235c0 100644 --- a/packages/core/src/h.ts +++ b/packages/core/src/h.ts @@ -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 +

( + tag: FunctionalComponent

, + data?: P & BuiltInProps | null, + children?: any + ): VNode + // stateful + >( + 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 index 0000000000..902d9f2ec9 --- /dev/null +++ b/packages/core/src/optional/mixin.ts @@ -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 {} +} diff --git a/packages/core/src/vdom.ts b/packages/core/src/vdom.ts index 0b1d948ad8..f54fe3b136 100644 --- a/packages/core/src/vdom.ts +++ b/packages/core/src/vdom.ts @@ -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 & 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,