types: props validation for h
This commit is contained in:
parent
81a31f79dc
commit
369b9eb583
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -24,6 +24,7 @@ export type VNodeTypes =
|
||||
| Function
|
||||
| Object
|
||||
| typeof Fragment
|
||||
| typeof Portal
|
||||
| typeof Text
|
||||
| typeof Empty
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user