types: improve typing

This commit is contained in:
Evan You 2019-10-08 12:43:13 -04:00
parent b68eb229c7
commit 8da5b007b1
13 changed files with 42 additions and 29 deletions

View File

@ -183,7 +183,7 @@ export function processExpression(
// range is offset by -1 due to the wrapping parens when parsed
const start = id.start - 1
const end = id.end - 1
const last = ids[i - 1] as any
const last = ids[i - 1]
const leadingText = rawExp.slice(last ? last.end - 1 : 0, start)
if (leadingText.length || id.prefix) {
children.push(leadingText + (id.prefix || ``))

View File

@ -157,7 +157,9 @@ export function createAppAPI<HostNode, HostElement>(
`It will be overwritten with the new value.`
)
}
context.provides[key as any] = value
// TypeScript doesn't allow symbols as index type
// https://github.com/Microsoft/TypeScript/issues/24587
context.provides[key as string] = value
}
}

View File

@ -20,7 +20,8 @@ export function provide<T>(key: InjectionKey<T> | string, value: T) {
if (parentProvides === provides) {
provides = currentInstance.provides = Object.create(parentProvides)
}
provides[key as any] = value
// TS doesn't allow symbol as index type
provides[key as string] = value
}
}
@ -30,7 +31,8 @@ export function inject(key: InjectionKey<any> | string, defaultValue?: any) {
if (currentInstance) {
const provides = currentInstance.provides
if (key in provides) {
return provides[key as any] as any
// TS doesn't allow symbol as index type
return provides[key as string]
} else if (defaultValue !== undefined) {
return defaultValue
} else if (__DEV__) {

View File

@ -185,7 +185,7 @@ export function applyOptions(
instance.renderContext === EMPTY_OBJ
? (instance.renderContext = reactive({}))
: instance.renderContext
const ctx = instance.renderProxy as any
const ctx = instance.renderProxy!
const {
// composition
mixins,
@ -265,7 +265,7 @@ export function applyOptions(
if (isString(raw)) {
const handler = renderContext[raw]
if (isFunction(handler)) {
watch(getter, handler as any)
watch(getter, handler as WatchHandler)
} else if (__DEV__) {
// TODO warn invalid watch handler path
}

View File

@ -210,7 +210,7 @@ export function instanceWatch(
cb: Function,
options?: WatchOptions
): () => void {
const ctx = this.renderProxy as any
const ctx = this.renderProxy!
const getter = isString(source) ? () => ctx[source] : source.bind(ctx)
const stop = watch(getter, cb.bind(ctx), options)
onBeforeUnmount(stop, this)

View File

@ -132,8 +132,8 @@ export function createComponentInstance(
type: vnode.type as Component,
root: null as any, // set later so it can point to itself
next: null,
subTree: null as any,
update: null as any,
subTree: null as any, // will be set synchronously right after creation
update: null as any, // will be set synchronously right after creation
render: null,
renderProxy: null,
propsProxy: null,

View File

@ -15,6 +15,7 @@ export type ComponentPublicInstance<
M = {},
PublicProps = P
> = {
[key: string]: any
$data: D
$props: PublicProps
$attrs: Data

View File

@ -40,7 +40,7 @@ export function renderComponentRoot(
slots,
emit
})
: render(props, null as any)
: render(props, null as any /* we know it doesn't it */)
)
}
} catch (err) {

View File

@ -11,11 +11,16 @@ import { ShapeFlags } from './shapeFlags'
import { warn } from './warning'
export type Slot = (...args: any[]) => VNodeChildren
export type Slots = Readonly<{
export type InternalSlots = {
[name: string]: Slot
}>
}
export type Slots = Readonly<InternalSlots>
export type RawSlots = {
[name: string]: unknown
_compiled?: boolean
}
const normalizeSlotValue = (value: unknown): VNode[] =>
@ -40,17 +45,18 @@ export function resolveSlots(
instance: ComponentInternalInstance,
children: NormalizedChildren
) {
let slots: Slots | void
let slots: InternalSlots | void
if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
if ((children as any)._compiled) {
const rawSlots = children as RawSlots
if (rawSlots._compiled) {
// pre-normalized slots object generated by compiler
slots = children as Slots
} else {
slots = {}
for (const key in children as RawSlots) {
let value = (children as RawSlots)[key]
for (const key in rawSlots) {
const value = rawSlots[key]
if (isFunction(value)) {
;(slots as any)[key] = normalizeSlot(key, value)
slots[key] = normalizeSlot(key, value)
} else if (value != null) {
if (__DEV__) {
warn(
@ -58,8 +64,8 @@ export function resolveSlots(
`Prefer function slots for better performance.`
)
}
value = normalizeSlotValue(value)
;(slots as any)[key] = () => value
const normalized = normalizeSlotValue(value)
slots[key] = () => normalized
}
}
}

View File

@ -1188,7 +1188,7 @@ export function createRenderer<
nextVNode.component = instance
instance.vnode = nextVNode
instance.next = null
resolveProps(instance, nextVNode.props, (nextVNode.type as any).props)
resolveProps(instance, nextVNode.props, (nextVNode.type as Component).props)
resolveSlots(instance, nextVNode.children)
}

View File

@ -104,7 +104,8 @@ export function applyDirectives(vnode: VNode, directives: DirectiveArguments) {
vnode = cloneVNode(vnode)
vnode.props = vnode.props != null ? extend({}, vnode.props) : {}
for (let i = 0; i < directives.length; i++) {
;(applyDirective as any)(vnode.props, instance, ...directives[i])
const [dir, value, arg, modifiers] = directives[i]
applyDirective(vnode.props, instance, dir, value, arg, modifiers)
}
} else if (__DEV__) {
warn(`applyDirectives can only be used inside render functions.`)

View File

@ -1,7 +1,8 @@
import { VNode, normalizeVNode } from './vnode'
import { VNode, normalizeVNode, VNodeChild } from './vnode'
import { ShapeFlags } from '.'
import { isFunction } from '@vue/shared'
import { ComponentInternalInstance } from './component'
import { Slots } from './componentSlots'
export const SuspenseSymbol = __DEV__ ? Symbol('Suspense key') : Symbol()
@ -62,14 +63,14 @@ export function normalizeSuspenseChildren(
} {
const { shapeFlag, children } = vnode
if (shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
const { default: d, fallback } = children as any
const { default: d, fallback } = children as Slots
return {
content: normalizeVNode(isFunction(d) ? d() : d),
fallback: normalizeVNode(isFunction(fallback) ? fallback() : fallback)
}
} else {
return {
content: normalizeVNode(children as any),
content: normalizeVNode(children as VNodeChild),
fallback: normalizeVNode(null)
}
}

View File

@ -5,9 +5,9 @@ import {
} from '@vue/runtime-core'
import { ErrorCodes } from 'packages/runtime-core/src/errorHandling'
interface Invoker extends Function {
interface Invoker extends EventListener {
value: EventValue
lastUpdated?: number
lastUpdated: number
}
type EventValue = (Function | Function[]) & {
@ -58,7 +58,7 @@ export function patchEvent(
el.addEventListener(name, createInvoker(nextValue, instance))
}
} else if (invoker) {
el.removeEventListener(name, invoker as any)
el.removeEventListener(name, invoker)
}
}
@ -66,7 +66,7 @@ function createInvoker(
initialValue: any,
instance: ComponentInternalInstance | null
) {
const invoker = ((e: Event) => {
const invoker: Invoker = (e: Event) => {
// async edge case #6566: inner click event triggers patch, event handler
// attached to outer element during patch, and triggered again. This
// happens because browsers fire microtask ticks between event propagation.
@ -94,7 +94,7 @@ function createInvoker(
)
}
}
}) as any
}
invoker.value = initialValue
initialValue.invoker = invoker
invoker.lastUpdated = getNow()