feat: fix all cases for h and options type inference

This commit is contained in:
Evan You
2019-09-05 18:48:49 -04:00
parent 6c7cbb0dc9
commit 94a05561f8
9 changed files with 83 additions and 85 deletions

View File

@@ -66,30 +66,20 @@ export interface LegacyOptions<
RawBindings,
D,
C extends ComputedOptions,
M extends MethodOptions,
ThisContext = ThisType<ComponentRenderProxy<Props, D, RawBindings, C, M>>
M extends MethodOptions
> {
el?: any
// state
data?:
| D
| (<This extends ComponentRenderProxy<Props, {}, RawBindings>>(
this: This
) => D)
computed?: C & ThisContext
methods?: M & ThisContext
data?: D | ((this: ComponentRenderProxy<Props>) => D)
computed?: C
methods?: M
// TODO watch array
watch?: Record<
string,
string | WatchHandler | { handler: WatchHandler } & WatchOptions
> &
ThisContext
provide?:
| Data
| (<This extends ComponentRenderProxy<Props, D, RawBindings, C, M>>(
this: This
) => any)
>
provide?: Data | Function
inject?:
| string[]
| Record<
@@ -102,10 +92,8 @@ export interface LegacyOptions<
extends?: LegacyComponent
// lifecycle
beforeCreate?(this: ComponentRenderProxy): void
created?<This extends ComponentRenderProxy<Props, D, RawBindings, C, M>>(
this: This
): void
beforeCreate?(): void
created?(): void
beforeMount?(): void
mounted?(): void
beforeUpdate?(): void

View File

@@ -18,14 +18,14 @@ export {
Ref,
ComputedRef,
UnwrapRef,
ComputedOptions
WritableComputedOptions
} from '@vue/reactivity'
import {
Ref,
computed as _computed,
ComputedRef,
ComputedOptions,
WritableComputedOptions,
ReactiveEffect
} from '@vue/reactivity'
@@ -40,7 +40,7 @@ export function recordEffect(effect: ReactiveEffect) {
}
export function computed<T>(getter: () => T): ComputedRef<T>
export function computed<T>(options: ComputedOptions<T>): Ref<T>
export function computed<T>(options: WritableComputedOptions<T>): Ref<T>
export function computed<T>(getterOrOptions: any) {
const c = _computed(getterOrOptions)
recordEffect(c.effect)

View File

@@ -37,8 +37,8 @@ export type Data = { [key: string]: unknown }
// in templates (as `this` in the render option)
export type ComponentRenderProxy<
P = {},
D = {},
B = {},
D = {},
C = {},
M = {},
PublicProps = P
@@ -52,17 +52,11 @@ export type ComponentRenderProxy<
$parent: ComponentInstance | null
$emit: (event: string, ...args: unknown[]) => void
} & P &
D &
UnwrapRef<B> &
D &
ExtracComputedReturns<C> &
M
type RenderFunction<P = {}, D = {}, B = {}, C = {}, M = {}> = <
This extends ComponentRenderProxy<P, D, B, C, M>
>(
this: This
) => VNodeChild
interface ComponentOptionsBase<
Props,
RawBindings,
@@ -71,47 +65,53 @@ interface ComponentOptionsBase<
M extends MethodOptions
> extends LegacyOptions<Props, RawBindings, D, C, M> {
setup?: (
this: null,
props: Props,
ctx: SetupContext
) => RawBindings | (() => VNodeChild) | void
name?: string
template?: string
render?: RenderFunction<Props, D, RawBindings, C, M>
// Note: we are intentionally using the signature-less `Function` type here
// since any type with signature will cause the whole inference to fail when
// the return expression contains reference to `this`.
// Luckily `render()` doesn't need any arguments nor does it care about return
// type.
render?: Function
components?: Record<string, Component>
directives?: Record<string, Directive>
}
export interface ComponentOptionsWithoutProps<
export type ComponentOptionsWithoutProps<
Props = {},
RawBindings = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {}
> extends ComponentOptionsBase<Props, RawBindings, D, C, M> {
> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
props?: undefined
}
} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
export interface ComponentOptionsWithArrayProps<
export type ComponentOptionsWithArrayProps<
PropNames extends string = string,
RawBindings = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {},
Props = { [key in PropNames]?: unknown }
> extends ComponentOptionsBase<Props, RawBindings, D, C, M> {
> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
props: PropNames[]
}
} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
export interface ComponentOptionsWithProps<
export type ComponentOptionsWithProps<
PropsOptions = ComponentPropsOptions,
RawBindings = {},
D = {},
C extends ComputedOptions = {},
M extends MethodOptions = {},
Props = ExtractPropTypes<PropsOptions>
> extends ComponentOptionsBase<Props, RawBindings, D, C, M> {
> = ComponentOptionsBase<Props, RawBindings, D, C, M> & {
props: PropsOptions
}
} & ThisType<ComponentRenderProxy<Props, RawBindings, D, C, M>>
export type ComponentOptions =
| ComponentOptionsWithoutProps
@@ -150,6 +150,8 @@ interface SetupContext {
emit: ((event: string, ...args: unknown[]) => void)
}
type RenderFunction = () => VNodeChild
export type ComponentInstance<P = Data, D = Data> = {
type: FunctionalComponent | ComponentOptions
parent: ComponentInstance | null
@@ -159,7 +161,7 @@ export type ComponentInstance<P = Data, D = Data> = {
next: VNode | null
subTree: VNode
update: ReactiveEffect
render: RenderFunction<P, D> | null
render: RenderFunction | null
effects: ReactiveEffect[] | null
provides: Data
@@ -211,7 +213,7 @@ export function createComponent<
>(
options: ComponentOptionsWithoutProps<Props, RawBindings, D, C, M>
): {
new (): ComponentRenderProxy<Props, D, RawBindings, C, M>
new (): ComponentRenderProxy<Props, RawBindings, D, C, M>
}
// overload 3: object format with array props declaration
// props inferred as { [key in PropNames]?: unknown }
@@ -227,8 +229,8 @@ export function createComponent<
): {
new (): ComponentRenderProxy<
{ [key in PropNames]?: unknown },
D,
RawBindings,
D,
C,
M
>
@@ -247,8 +249,8 @@ export function createComponent<
// for Vetur and TSX support
new (): ComponentRenderProxy<
ExtractPropTypes<PropsOptions>,
D,
RawBindings,
D,
C,
M,
ExtractPropTypes<PropsOptions, false>

View File

@@ -11,10 +11,10 @@ import { Ref } from '@vue/reactivity'
import { RawSlots } from './componentSlots'
import {
FunctionalComponent,
ComponentOptions,
ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps,
ComponentOptionsWithProps
ComponentOptionsWithProps,
ComponentOptions
} from './component'
import { ExtractPropTypes } from './componentProps'
@@ -57,7 +57,7 @@ interface Props {
[Symbol.iterator]?: never
}
type Children = string | number | VNodeChildren
type Children = string | number | boolean | VNodeChildren | (() => any)
// fake constructor type returned from `createComponent`
interface Constructor<P = any> {

View File

@@ -28,7 +28,7 @@ export type VNodeTypes =
| typeof Text
| typeof Empty
type VNodeChildAtom = VNode | string | number | null | void
type VNodeChildAtom = VNode | string | number | boolean | null | void
export interface VNodeChildren extends Array<VNodeChildren | VNodeChildAtom> {}
export type VNodeChild = VNodeChildAtom | VNodeChildren