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

View File

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

View File

@ -16,7 +16,11 @@ import {
import { warn } from './warning'
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
}

View File

@ -13,7 +13,8 @@ import {
ComponentInternalInstance,
createComponentInstance,
setupStatefulComponent,
handleSetupResult
handleSetupResult,
Component
} from './component'
import {
renderComponentRoot,
@ -1006,7 +1007,7 @@ export function createRenderer<
}
// 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)
resolveSlots(instance, initialVNode.children)

View File

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

View File

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

View File

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

View File

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