]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
types: props validation for h
authorEvan You <yyx990803@gmail.com>
Thu, 5 Sep 2019 15:11:33 +0000 (11:11 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 5 Sep 2019 15:11:33 +0000 (11:11 -0400)
packages/runtime-core/src/apiOptions.ts
packages/runtime-core/src/component.ts
packages/runtime-core/src/h.ts
packages/runtime-core/src/vnode.ts

index 472462cf715077b20190ef8e12ffb6b11c11b49e..7ed2590a7b02712586c98d241c2d8edf3da20703 100644 (file)
@@ -16,7 +16,7 @@ import {
   camelize
 } from '@vue/shared'
 import { computed, ComputedOptions } from './apiReactivity'
-import { watch } from './apiWatch'
+import { watch, WatchOptions } from './apiWatch'
 import { provide, inject } from './apiInject'
 import {
   onBeforeMount,
@@ -45,16 +45,14 @@ export interface LegacyOptions {
   // TODO watch array
   watch?: Record<
     string,
-    | string
-    | Function
-    | { handler: Function; deep?: boolean; immediate: boolean }
+    string | Function | { handler: Function } & WatchOptions
   >
   provide?: Data | (() => Data)
   inject?:
     | string[]
     | Record<
         string | symbol,
-        string | symbol | { from: string | symbol; default: any }
+        string | symbol | { from: string | symbol; default?: any }
       >
 
   // composition
index c3ac0b5253f4d28ffdf46c9d4f2a0d73667f48f5..afd9a98a0e41bb51e64118124eb6cfaa484f1754 100644 (file)
@@ -58,12 +58,12 @@ interface ComponentOptionsBase<Props, RawBindings> extends LegacyOptions {
   directives?: Record<string, Directive>
 }
 
-interface ComponentOptionsWithoutProps<Props = {}, RawBindings = {}>
+export interface ComponentOptionsWithoutProps<Props = {}, RawBindings = {}>
   extends ComponentOptionsBase<Props, RawBindings> {
   props?: undefined
 }
 
-interface ComponentOptionsWithArrayProps<
+export interface ComponentOptionsWithArrayProps<
   PropNames extends string = string,
   RawBindings = {},
   Props = { [key in PropNames]?: unknown }
@@ -71,7 +71,7 @@ interface ComponentOptionsWithArrayProps<
   props: PropNames[]
 }
 
-interface ComponentOptionsWithProps<
+export interface ComponentOptionsWithProps<
   PropsOptions = ComponentPropsOptions,
   RawBindings = {},
   Props = ExtractPropTypes<PropsOptions>
index df16598cd6c7f50903c58570f61507dae6007107..c2ff1bed7d5a152cf7558a80a95d86b845173520 100644 (file)
@@ -1,5 +1,22 @@
-import { VNodeTypes, VNode, createVNode } from './vnode'
+import {
+  VNodeTypes,
+  VNode,
+  createVNode,
+  VNodeChildren,
+  Fragment,
+  Portal
+} from './vnode'
 import { isObject, isArray } from '@vue/shared'
+import { Ref } from '@vue/reactivity'
+import { RawSlots } from './componentSlots'
+import {
+  FunctionalComponent,
+  ComponentOptions,
+  ComponentOptionsWithoutProps,
+  ComponentOptionsWithArrayProps,
+  ComponentOptionsWithProps
+} from './component'
+import { ExtractPropTypes } from './componentProps'
 
 // `h` is a more user-friendly version of `createVNode` that allows omitting the
 // props when possible. It is intended for manually written render functions.
@@ -30,6 +47,87 @@ h('div', {}, 'foo') // text
 h('div', null, {})
 **/
 
+interface Props {
+  [key: string]: any
+  key?: string | number
+  ref?: string | Ref<any> | Function
+  // used to differ from a single VNode object as children
+  _isVNode?: never
+  // used to differ from Array children
+  [Symbol.iterator]?: never
+}
+
+type Children = string | number | VNodeChildren
+
+// fake constructor type returned from `createComponent`
+interface Constructor<P = any> {
+  new (): { $props: P }
+}
+
+// The following is a series of overloads for providing props validation of
+// manually written render functions.
+
+// element
+export function h(type: string, children?: Children): VNode
+export function h(
+  type: string,
+  props?: Props | null,
+  children?: Children
+): VNode
+
+// keyed fragment
+export function h(type: typeof Fragment, children?: Children): VNode
+export function h(
+  type: typeof Fragment,
+  props?: (Props & { key?: string | number }) | null,
+  children?: Children
+): VNode
+
+// portal
+export function h(type: typeof Portal, children?: Children): VNode
+export function h(
+  type: typeof Portal,
+  props?: (Props & { target: any }) | null,
+  children?: Children
+): VNode
+
+// functional component
+export function h(type: FunctionalComponent, children?: Children): VNode
+export function h<P>(
+  type: FunctionalComponent<P>,
+  props?: (Props & P) | null,
+  children?: Children | RawSlots
+): VNode
+
+// stateful component
+export function h(type: ComponentOptions, children?: Children): VNode
+export function h<P>(
+  type: ComponentOptionsWithoutProps<P>,
+  props?: (Props & P) | null,
+  children?: Children | RawSlots
+): VNode
+export function h<P extends string>(
+  type: ComponentOptionsWithArrayProps<P>,
+  // TODO for now this doesn't really do anything, but it would become useful
+  // if we make props required by default
+  props?: (Props & { [key in P]?: any }) | null,
+  children?: Children | RawSlots
+): VNode
+export function h<P>(
+  type: ComponentOptionsWithProps<P>,
+  props?: (Props & ExtractPropTypes<P>) | null,
+  children?: Children | RawSlots
+): VNode
+
+// fake constructor type returned by `createComponent`
+export function h(type: Constructor, children?: Children): VNode
+export function h<P>(
+  type: Constructor<P>,
+  props?: (Props & P) | null,
+  children?: Children | RawSlots
+): VNode
+
+// Actual implementation
 export function h(
   type: VNodeTypes,
   propsOrChildren?: any,
index 358106459e434dce1a726033a73faca1a23509ed..57b5b141177137d42caff8a194b1b1dfb2c16dcb 100644 (file)
@@ -24,6 +24,7 @@ export type VNodeTypes =
   | Function
   | Object
   | typeof Fragment
+  | typeof Portal
   | typeof Text
   | typeof Empty