types: improve typing

This commit is contained in:
Evan You 2019-10-08 09:26:09 -04:00
parent 016231d09f
commit 1393ee52ca
8 changed files with 42 additions and 24 deletions

View File

@ -3,7 +3,7 @@ import {
MethodOptions, MethodOptions,
ComponentOptionsWithoutProps, ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps, ComponentOptionsWithArrayProps,
ComponentOptionsWithProps ComponentOptionsWithObjectProps
} from './apiOptions' } from './apiOptions'
import { SetupContext } from './component' import { SetupContext } from './component'
import { VNodeChild } from './vnode' import { VNodeChild } from './vnode'
@ -62,7 +62,7 @@ export function createComponent<
C extends ComputedOptions = {}, C extends ComputedOptions = {},
M extends MethodOptions = {} M extends MethodOptions = {}
>( >(
options: ComponentOptionsWithProps<PropsOptions, RawBindings, D, C, M> options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M>
): { ): {
// for Vetur and TSX support // for Vetur and TSX support
new (): ComponentPublicInstance< new (): ComponentPublicInstance<

View File

@ -27,7 +27,7 @@ import {
onRenderTriggered onRenderTriggered
} from './apiLifecycle' } from './apiLifecycle'
import { DebuggerEvent, reactive } from '@vue/reactivity' import { DebuggerEvent, reactive } from '@vue/reactivity'
import { ComponentPropsOptions, ExtractPropTypes } from './componentProps' import { ComponentObjectPropsOptions, ExtractPropTypes } from './componentProps'
import { Directive } from './directives' import { Directive } from './directives'
import { VNodeChild } from './vnode' import { VNodeChild } from './vnode'
import { ComponentPublicInstance } from './componentProxy' import { ComponentPublicInstance } from './componentProxy'
@ -78,8 +78,8 @@ export type ComponentOptionsWithArrayProps<
props: PropNames[] props: PropNames[]
} & ThisType<ComponentPublicInstance<Props, RawBindings, D, C, M>> } & ThisType<ComponentPublicInstance<Props, RawBindings, D, C, M>>
export type ComponentOptionsWithProps< export type ComponentOptionsWithObjectProps<
PropsOptions = ComponentPropsOptions, PropsOptions = ComponentObjectPropsOptions,
RawBindings = {}, RawBindings = {},
D = {}, D = {},
C extends ComputedOptions = {}, C extends ComputedOptions = {},
@ -91,7 +91,7 @@ export type ComponentOptionsWithProps<
export type ComponentOptions = export type ComponentOptions =
| ComponentOptionsWithoutProps | ComponentOptionsWithoutProps
| ComponentOptionsWithProps | ComponentOptionsWithObjectProps
| ComponentOptionsWithArrayProps | ComponentOptionsWithArrayProps
// TODO legacy component definition also supports constructors with .options // TODO legacy component definition also supports constructors with .options

View File

@ -16,7 +16,11 @@ import {
import { warn } from './warning' import { warn } from './warning'
import { Data, ComponentInternalInstance } from './component' import { Data, ComponentInternalInstance } from './component'
export type ComponentPropsOptions<P = Data> = { export type ComponentPropsOptions<P = Data> =
| ComponentObjectPropsOptions<P>
| string[]
export type ComponentObjectPropsOptions<P = Data> = {
[K in keyof P]: Prop<P[K]> | null [K in keyof P]: Prop<P[K]> | null
} }

View File

@ -13,7 +13,8 @@ import {
ComponentInternalInstance, ComponentInternalInstance,
createComponentInstance, createComponentInstance,
setupStatefulComponent, setupStatefulComponent,
handleSetupResult handleSetupResult,
Component
} from './component' } from './component'
import { import {
renderComponentRoot, renderComponentRoot,
@ -1006,7 +1007,7 @@ export function createRenderer<
} }
// resolve props and slots for setup context // resolve props and slots for setup context
const propsOptions = (initialVNode.type as any).props const propsOptions = (initialVNode.type as Component).props
resolveProps(instance, initialVNode.props, propsOptions) resolveProps(instance, initialVNode.props, propsOptions)
resolveSlots(instance, initialVNode.children) resolveSlots(instance, initialVNode.children)

View File

@ -13,7 +13,7 @@ import { FunctionalComponent } from './component'
import { import {
ComponentOptionsWithoutProps, ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps, ComponentOptionsWithArrayProps,
ComponentOptionsWithProps, ComponentOptionsWithObjectProps,
ComponentOptions ComponentOptions
} from './apiOptions' } from './apiOptions'
import { ExtractPropTypes } from './componentProps' import { ExtractPropTypes } from './componentProps'
@ -121,7 +121,7 @@ export function h<P extends string>(
children?: RawChildren | RawSlots children?: RawChildren | RawSlots
): VNode ): VNode
export function h<P>( export function h<P>(
type: ComponentOptionsWithProps<P>, type: ComponentOptionsWithObjectProps<P>,
props?: (RawProps & ExtractPropTypes<P>) | null, props?: (RawProps & ExtractPropTypes<P>) | null,
children?: RawChildren | RawSlots children?: RawChildren | RawSlots
): VNode ): VNode

View File

@ -63,14 +63,19 @@ export {
export { export {
ComponentOptions, ComponentOptions,
ComponentOptionsWithoutProps, ComponentOptionsWithoutProps,
ComponentOptionsWithProps, ComponentOptionsWithObjectProps as ComponentOptionsWithProps,
ComponentOptionsWithArrayProps ComponentOptionsWithArrayProps
} from './apiOptions' } from './apiOptions'
export { ComponentPublicInstance } from './componentProxy' export { ComponentPublicInstance } from './componentProxy'
export { RendererOptions } from './createRenderer' export { RendererOptions } from './createRenderer'
export { Slot, Slots } from './componentSlots' export { Slot, Slots } from './componentSlots'
export { Prop, PropType, ComponentPropsOptions } from './componentProps' export {
Prop,
PropType,
ComponentPropsOptions,
ComponentObjectPropsOptions
} from './componentProps'
export { export {
Directive, Directive,
DirectiveBinding, DirectiveBinding,

View File

@ -7,7 +7,12 @@ import {
extend, extend,
PatchFlags PatchFlags
} from '@vue/shared' } from '@vue/shared'
import { ComponentInternalInstance, Data, SetupProxySymbol } from './component' import {
ComponentInternalInstance,
Data,
SetupProxySymbol,
Component
} from './component'
import { RawSlots } from './componentSlots' import { RawSlots } from './componentSlots'
import { ShapeFlags } from './shapeFlags' import { ShapeFlags } from './shapeFlags'
import { isReactive } from '@vue/reactivity' import { isReactive } from '@vue/reactivity'
@ -22,8 +27,7 @@ export const Suspense = __DEV__ ? Symbol('Suspense') : Symbol()
export type VNodeTypes = export type VNodeTypes =
| string | string
| Function | Component
| Object
| typeof Fragment | typeof Fragment
| typeof Portal | typeof Portal
| typeof Text | typeof Text

View File

@ -1,18 +1,22 @@
import { VNode } from './vnode' import { VNode } from './vnode'
import { Data, ComponentInternalInstance } from './component' import { Data, ComponentInternalInstance, Component } from './component'
import { isString } from '@vue/shared' import { isString, isFunction } from '@vue/shared'
import { toRaw } from '@vue/reactivity' import { toRaw } from '@vue/reactivity'
type ComponentVNode = VNode & {
type: Component
}
let stack: VNode[] = [] let stack: VNode[] = []
type TraceEntry = { type TraceEntry = {
vnode: VNode vnode: ComponentVNode
recurseCount: number recurseCount: number
} }
type ComponentTraceStack = TraceEntry[] type ComponentTraceStack = TraceEntry[]
export function pushWarningContext(vnode: VNode) { export function pushWarningContext(vnode: ComponentVNode) {
stack.push(vnode) stack.push(vnode)
} }
@ -117,9 +121,9 @@ const classifyRE = /(?:^|[-_])(\w)/g
const classify = (str: string): string => const classify = (str: string): string =>
str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '') str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '')
function formatComponentName(vnode: VNode, file?: string): string { function formatComponentName(vnode: ComponentVNode, file?: string): string {
const Component = vnode.type as any const Component = vnode.type
let name = Component.displayName || Component.name let name = isFunction(Component) ? Component.displayName : Component.name
if (!name && file) { if (!name && file) {
const match = file.match(/([^/\\]+)\.vue$/) const match = file.match(/([^/\\]+)\.vue$/)
if (match) { if (match) {
@ -136,7 +140,7 @@ function formatProps(props: Data): string[] {
if (isString(value)) { if (isString(value)) {
res.push(`${key}=${JSON.stringify(value)}`) res.push(`${key}=${JSON.stringify(value)}`)
} else { } else {
res.push(`${key}=`, toRaw(value) as any) res.push(`${key}=`, String(toRaw(value)))
} }
} }
return res return res