types: simplify types (#104)

This commit is contained in:
月迷津渡 2019-10-05 22:09:34 +08:00 committed by Evan You
parent ca70aff860
commit 9d6783053c
12 changed files with 50 additions and 71 deletions

View File

@ -1,4 +1,4 @@
import { Component, Data, ComponentInternalInstance } from './component' import { Component, Data } from './component'
import { ComponentOptions } from './apiOptions' import { ComponentOptions } from './apiOptions'
import { ComponentPublicInstance } from './componentProxy' import { ComponentPublicInstance } from './componentProxy'
import { Directive } from './directives' import { Directive } from './directives'
@ -142,7 +142,7 @@ export function createAppAPI<HostNode, HostElement>(
vnode.appContext = context vnode.appContext = context
render(vnode, rootContainer) render(vnode, rootContainer)
isMounted = true isMounted = true
return (vnode.component as ComponentInternalInstance).renderProxy return vnode.component!.renderProxy
} else if (__DEV__) { } else if (__DEV__) {
warn( warn(
`App has already been mounted. Create a new app instance instead.` `App has already been mounted. Create a new app instance instead.`

View File

@ -77,5 +77,5 @@ export function createComponent<
// implementation, close to no-op // implementation, close to no-op
export function createComponent(options: any) { export function createComponent(options: any) {
return isFunction(options) ? { setup: options } : (options as any) return isFunction(options) ? { setup: options } : options
} }

View File

@ -225,7 +225,7 @@ export function setupStatefulComponent(
) { ) {
const Component = instance.type as ComponentOptions const Component = instance.type as ComponentOptions
// 1. create render proxy // 1. create render proxy
instance.renderProxy = new Proxy(instance, PublicInstanceProxyHandlers) as any instance.renderProxy = new Proxy(instance, PublicInstanceProxyHandlers)
// 2. create props proxy // 2. create props proxy
// the propsProxy is a reactive AND readonly proxy to the actual props. // the propsProxy is a reactive AND readonly proxy to the actual props.
// it will be updated in resolveProps() on updates before render // it will be updated in resolveProps() on updates before render
@ -255,7 +255,7 @@ export function setupStatefulComponent(
if (__FEATURE_SUSPENSE__) { if (__FEATURE_SUSPENSE__) {
// async setup returned Promise. // async setup returned Promise.
// bail here and wait for re-entry. // bail here and wait for re-entry.
instance.asyncDep = setupResult as Promise<any> instance.asyncDep = setupResult
} else if (__DEV__) { } else if (__DEV__) {
warn( warn(
`setup() returned a Promise, but the version of Vue you are using ` + `setup() returned a Promise, but the version of Vue you are using ` +
@ -358,10 +358,9 @@ export const SetupProxySymbol = Symbol()
const SetupProxyHandlers: { [key: string]: ProxyHandler<any> } = {} const SetupProxyHandlers: { [key: string]: ProxyHandler<any> } = {}
;['attrs', 'slots', 'refs'].forEach((type: string) => { ;['attrs', 'slots', 'refs'].forEach((type: string) => {
SetupProxyHandlers[type] = { SetupProxyHandlers[type] = {
get: (instance, key) => (instance[type] as any)[key], get: (instance, key) => instance[type][key],
has: (instance, key) => has: (instance, key) => key === SetupProxySymbol || key in instance[type],
key === SetupProxySymbol || key in (instance[type] as any), ownKeys: instance => Reflect.ownKeys(instance[type]),
ownKeys: instance => Reflect.ownKeys(instance[type] as any),
// this is necessary for ownKeys to work properly // this is necessary for ownKeys to work properly
getOwnPropertyDescriptor: (instance, key) => getOwnPropertyDescriptor: (instance, key) =>
Reflect.getOwnPropertyDescriptor(instance[type], key), Reflect.getOwnPropertyDescriptor(instance[type], key),
@ -379,6 +378,6 @@ function createSetupContext(instance: ComponentInternalInstance): SetupContext {
slots: new Proxy(instance, SetupProxyHandlers.slots), slots: new Proxy(instance, SetupProxyHandlers.slots),
refs: new Proxy(instance, SetupProxyHandlers.refs), refs: new Proxy(instance, SetupProxyHandlers.refs),
emit: instance.emit emit: instance.emit
} as any }
return __DEV__ ? Object.freeze(context) : context return __DEV__ ? Object.freeze(context) : context
} }

View File

@ -96,7 +96,7 @@ export function resolveProps(
_options: ComponentPropsOptions | void _options: ComponentPropsOptions | void
) { ) {
const hasDeclaredProps = _options != null const hasDeclaredProps = _options != null
const options = normalizePropsOptions(_options) as NormalizedPropsOptions const options = normalizePropsOptions(_options)!
if (!rawProps && !hasDeclaredProps) { if (!rawProps && !hasDeclaredProps) {
return return
} }
@ -196,9 +196,9 @@ const normalizationMap = new WeakMap()
function normalizePropsOptions( function normalizePropsOptions(
raw: ComponentPropsOptions | void raw: ComponentPropsOptions | void
): NormalizedPropsOptions | void { ): NormalizedPropsOptions | null {
if (!raw) { if (!raw) {
return return null
} }
if (normalizationMap.has(raw)) { if (normalizationMap.has(raw)) {
return normalizationMap.get(raw) return normalizationMap.get(raw)

View File

@ -38,7 +38,7 @@ export const PublicInstanceProxyHandlers = {
return renderContext[key] return renderContext[key]
} else if (hasOwn(props, key)) { } else if (hasOwn(props, key)) {
// return the value from propsProxy for ref unwrapping and readonly // return the value from propsProxy for ref unwrapping and readonly
return (propsProxy as any)[key] return propsProxy![key]
} else { } else {
// TODO simplify this? // TODO simplify this?
switch (key) { switch (key) {

View File

@ -29,7 +29,7 @@ export function renderComponentRoot(
currentRenderingInstance = instance currentRenderingInstance = instance
try { try {
if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) { if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
result = normalizeVNode((instance.render as Function).call(renderProxy)) result = normalizeVNode(instance.render!.call(renderProxy))
} else { } else {
// functional // functional
const render = Component as FunctionalComponent const render = Component as FunctionalComponent
@ -66,12 +66,12 @@ export function shouldUpdateComponent(
} }
if (patchFlag & PatchFlags.FULL_PROPS) { if (patchFlag & PatchFlags.FULL_PROPS) {
// presence of this flag indicates props are always non-null // presence of this flag indicates props are always non-null
return hasPropsChanged(prevProps as Data, nextProps as Data) return hasPropsChanged(prevProps!, nextProps!)
} else if (patchFlag & PatchFlags.PROPS) { } else if (patchFlag & PatchFlags.PROPS) {
const dynamicProps = nextVNode.dynamicProps as string[] const dynamicProps = nextVNode.dynamicProps!
for (let i = 0; i < dynamicProps.length; i++) { for (let i = 0; i < dynamicProps.length; i++) {
const key = dynamicProps[i] const key = dynamicProps[i]
if ((nextProps as any)[key] !== (prevProps as any)[key]) { if (nextProps![key] !== prevProps![key]) {
return true return true
} }
} }

View File

@ -60,12 +60,8 @@ function createDevEffectOptions(
): ReactiveEffectOptions { ): ReactiveEffectOptions {
return { return {
scheduler: queueJob, scheduler: queueJob,
onTrack: instance.rtc onTrack: instance.rtc ? e => invokeHooks(instance.rtc!, e) : void 0,
? e => invokeHooks(instance.rtc as Function[], e) onTrigger: instance.rtg ? e => invokeHooks(instance.rtg!, e) : void 0
: void 0,
onTrigger: instance.rtg
? e => invokeHooks(instance.rtg as Function[], e)
: void 0
} }
} }
@ -449,7 +445,7 @@ export function createRenderer<
// bail out and go through a full diff because we need to unset the old key // bail out and go through a full diff because we need to unset the old key
if (patchFlag & PatchFlags.PROPS) { if (patchFlag & PatchFlags.PROPS) {
// if the flag is present then dynamicProps must be non-null // if the flag is present then dynamicProps must be non-null
const propsToUpdate = n2.dynamicProps as string[] const propsToUpdate = n2.dynamicProps!
for (let i = 0; i < propsToUpdate.length; i++) { for (let i = 0; i < propsToUpdate.length; i++) {
const key = propsToUpdate[i] const key = propsToUpdate[i]
const prev = oldProps[key] const prev = oldProps[key]
@ -495,7 +491,7 @@ export function createRenderer<
if (dynamicChildren != null) { if (dynamicChildren != null) {
// children fast path // children fast path
const olddynamicChildren = n1.dynamicChildren as HostVNode[] const olddynamicChildren = n1.dynamicChildren!
for (let i = 0; i < dynamicChildren.length; i++) { for (let i = 0; i < dynamicChildren.length; i++) {
patch( patch(
olddynamicChildren[i], olddynamicChildren[i],
@ -579,12 +575,10 @@ export function createRenderer<
isSVG: boolean, isSVG: boolean,
optimized: boolean optimized: boolean
) { ) {
const fragmentStartAnchor = (n2.el = n1 const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateComment(''))!
? n1.el
: hostCreateComment('')) as HostNode
const fragmentEndAnchor = (n2.anchor = n1 const fragmentEndAnchor = (n2.anchor = n1
? n1.anchor ? n1.anchor
: hostCreateComment('')) as HostNode : hostCreateComment(''))!
if (n1 == null) { if (n1 == null) {
hostInsert(fragmentStartAnchor, container, anchor) hostInsert(fragmentStartAnchor, container, anchor)
hostInsert(fragmentEndAnchor, container, anchor) hostInsert(fragmentEndAnchor, container, anchor)
@ -647,7 +641,7 @@ export function createRenderer<
} }
} else { } else {
// update content // update content
const target = (n2.target = n1.target) as HostElement const target = (n2.target = n1.target)!
if (patchFlag === PatchFlags.TEXT) { if (patchFlag === PatchFlags.TEXT) {
hostSetElementText(target, children as string) hostSetElementText(target, children as string)
} else if (!optimized) { } else if (!optimized) {
@ -783,7 +777,7 @@ export function createRenderer<
isSVG: boolean, isSVG: boolean,
optimized: boolean optimized: boolean
) { ) {
const suspense = (n2.suspense = n1.suspense) as HostSuspsenseBoundary const suspense = (n2.suspense = n1.suspense)!
suspense.vnode = n2 suspense.vnode = n2
const { content, fallback } = normalizeSuspenseChildren(n2) const { content, fallback } = normalizeSuspenseChildren(n2)
const oldSubTree = suspense.subTree const oldSubTree = suspense.subTree
@ -959,8 +953,7 @@ export function createRenderer<
isSVG isSVG
) )
} else { } else {
const instance = (n2.component = const instance = (n2.component = n1.component)!
n1.component) as ComponentInternalInstance
if (shouldUpdateComponent(n1, n2, optimized)) { if (shouldUpdateComponent(n1, n2, optimized)) {
if ( if (
@ -991,12 +984,7 @@ export function createRenderer<
} }
} }
if (n2.ref !== null && parentComponent !== null) { if (n2.ref !== null && parentComponent !== null) {
setRef( setRef(n2.ref, n1 && n1.ref, parentComponent, n2.component!.renderProxy)
n2.ref,
n1 && n1.ref,
parentComponent,
(n2.component as ComponentInternalInstance).renderProxy
)
} }
} }
@ -1601,7 +1589,7 @@ export function createRenderer<
return return
} }
if (__FEATURE_SUSPENSE__ && vnode.type === Suspense) { if (__FEATURE_SUSPENSE__ && vnode.type === Suspense) {
const suspense = vnode.suspense as SuspenseBoundary const suspense = vnode.suspense!
move( move(
suspense.isResolved ? suspense.subTree : suspense.fallbackTree, suspense.isResolved ? suspense.subTree : suspense.fallbackTree,
container, container,
@ -1611,14 +1599,14 @@ export function createRenderer<
return return
} }
if (vnode.type === Fragment) { if (vnode.type === Fragment) {
hostInsert(vnode.el as HostNode, container, anchor) hostInsert(vnode.el!, container, anchor)
const children = vnode.children as HostVNode[] const children = vnode.children as HostVNode[]
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
move(children[i], container, anchor) move(children[i], container, anchor)
} }
hostInsert(vnode.anchor as HostNode, container, anchor) hostInsert(vnode.anchor!, container, anchor)
} else { } else {
hostInsert(vnode.el as HostNode, container, anchor) hostInsert(vnode.el!, container, anchor)
} }
} }
@ -1677,7 +1665,7 @@ export function createRenderer<
} }
if (doRemove) { if (doRemove) {
hostRemove(vnode.el as HostNode) hostRemove(vnode.el!)
if (anchor != null) hostRemove(anchor) if (anchor != null) hostRemove(anchor)
} }
@ -1742,19 +1730,9 @@ export function createRenderer<
doRemove?: boolean doRemove?: boolean
) { ) {
suspense.isUnmounted = true suspense.isUnmounted = true
unmount( unmount(suspense.subTree, parentComponent, parentSuspense, doRemove)
suspense.subTree as HostVNode,
parentComponent,
parentSuspense,
doRemove
)
if (!suspense.isResolved) { if (!suspense.isResolved) {
unmount( unmount(suspense.fallbackTree, parentComponent, parentSuspense, doRemove)
suspense.fallbackTree as HostVNode,
parentComponent,
parentSuspense,
doRemove
)
} }
} }
@ -1784,7 +1762,7 @@ export function createRenderer<
suspense.isResolved ? suspense.subTree : suspense.fallbackTree suspense.isResolved ? suspense.subTree : suspense.fallbackTree
) )
} }
return hostNextSibling((anchor || el) as HostNode) return hostNextSibling((anchor || el)!)
} }
function setRef( function setRef(

View File

@ -55,13 +55,13 @@ function applyDirective(
arg?: string, arg?: string,
modifiers?: DirectiveModifiers modifiers?: DirectiveModifiers
) { ) {
let valueCacheForDir = valueCache.get(directive) as WeakMap<VNode, any> let valueCacheForDir = valueCache.get(directive)!
if (!valueCacheForDir) { if (!valueCacheForDir) {
valueCacheForDir = new WeakMap<VNode, any>() valueCacheForDir = new WeakMap<VNode, any>()
valueCache.set(directive, valueCacheForDir) valueCache.set(directive, valueCacheForDir)
} }
for (const key in directive) { for (const key in directive) {
const hook = directive[key as keyof Directive] as DirectiveHook const hook = directive[key as keyof Directive]!
const hookKey = `vnode` + key[0].toUpperCase() + key.slice(1) const hookKey = `vnode` + key[0].toUpperCase() + key.slice(1)
const vnodeHook = (vnode: VNode, prevVNode: VNode | null) => { const vnodeHook = (vnode: VNode, prevVNode: VNode | null) => {
let oldValue let oldValue
@ -85,7 +85,7 @@ function applyDirective(
} }
const existing = props[hookKey] const existing = props[hookKey]
props[hookKey] = existing props[hookKey] = existing
? [].concat(existing as any, vnodeHook as any) ? [].concat(existing, vnodeHook as any)
: vnodeHook : vnodeHook
} }
} }

View File

@ -72,7 +72,7 @@ export function callWithAsyncErrorHandling(
) { ) {
const res = callWithErrorHandling(fn, instance, type, args) const res = callWithErrorHandling(fn, instance, type, args)
if (res != null && !res._isVue && typeof res.then === 'function') { if (res != null && !res._isVue && typeof res.then === 'function') {
;(res as Promise<any>).catch(err => { res.catch((err: any) => {
handleError(err, instance, type) handleError(err, instance, type)
}) })
} }

View File

@ -5,13 +5,18 @@ import { camelize, capitalize } from '@vue/shared'
import { warn } from '../warning' import { warn } from '../warning'
export function resolveComponent(name: string): Component | undefined { export function resolveComponent(name: string): Component | undefined {
return resolveAsset('components', name) as any return resolveAsset('components', name)
} }
export function resolveDirective(name: string): Directive | undefined { export function resolveDirective(name: string): Directive | undefined {
return resolveAsset('directives', name) as any return resolveAsset('directives', name)
} }
// overload 1: components
function resolveAsset(type: 'components', name: string): Component | undefined
// overload 2: directives
function resolveAsset(type: 'directives', name: string): Directive | undefined
function resolveAsset(type: 'components' | 'directives', name: string) { function resolveAsset(type: 'components' | 'directives', name: string) {
const instance = currentRenderingInstance || currentInstance const instance = currentRenderingInstance || currentInstance
if (instance) { if (instance) {

View File

@ -53,11 +53,11 @@ function flushJobs(seenJobs?: JobCountMap) {
} }
while ((job = queue.shift())) { while ((job = queue.shift())) {
if (__DEV__) { if (__DEV__) {
const seen = seenJobs as JobCountMap const seen = seenJobs!
if (!seen.has(job)) { if (!seen.has(job)) {
seen.set(job, 1) seen.set(job, 1)
} else { } else {
const count = seen.get(job) as number const count = seen.get(job)!
if (count > RECURSION_LIMIT) { if (count > RECURSION_LIMIT) {
throw new Error( throw new Error(
'Maximum recursive updates exceeded. ' + 'Maximum recursive updates exceeded. ' +

View File

@ -77,7 +77,7 @@ function getComponentTrace(): ComponentTraceStack {
recurseCount: 0 recurseCount: 0
}) })
} }
const parentInstance: ComponentInternalInstance | null = (currentVNode.component as ComponentInternalInstance) const parentInstance: ComponentInternalInstance | null = currentVNode.component!
.parent .parent
currentVNode = parentInstance && parentInstance.vnode currentVNode = parentInstance && parentInstance.vnode
} }
@ -107,10 +107,7 @@ function formatTraceEntry(
recurseCount > 0 ? `... (${recurseCount} recursive calls)` : `` recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``
const open = padding + `<${formatComponentName(vnode)}` const open = padding + `<${formatComponentName(vnode)}`
const close = `>` + postfix const close = `>` + postfix
const rootLabel = const rootLabel = vnode.component!.parent == null ? `(Root)` : ``
(vnode.component as ComponentInternalInstance).parent == null
? `(Root)`
: ``
return vnode.props return vnode.props
? [open, ...formatProps(vnode.props), close, rootLabel] ? [open, ...formatProps(vnode.props), close, rootLabel]
: [open + close, rootLabel] : [open + close, rootLabel]