Parcourir la source

types: improve typing

Evan You il y a 6 ans
Parent
commit
1393ee52ca

+ 2 - 2
packages/runtime-core/src/apiCreateComponent.ts

@@ -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<

+ 4 - 4
packages/runtime-core/src/apiOptions.ts

@@ -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

+ 5 - 1
packages/runtime-core/src/componentProps.ts

@@ -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
 }
 

+ 3 - 2
packages/runtime-core/src/createRenderer.ts

@@ -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)
 

+ 2 - 2
packages/runtime-core/src/h.ts

@@ -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

+ 7 - 2
packages/runtime-core/src/index.ts

@@ -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,

+ 7 - 3
packages/runtime-core/src/vnode.ts

@@ -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

+ 12 - 8
packages/runtime-core/src/warning.ts

@@ -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