fix(types): make return type of defineComponent
assignable to Component
type (#1032)
fix #993
This commit is contained in:
parent
28b4c317b4
commit
f3a9b516bd
@ -11,7 +11,8 @@ import {
|
|||||||
watch,
|
watch,
|
||||||
watchEffect,
|
watchEffect,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onErrorCaptured
|
onErrorCaptured,
|
||||||
|
Component
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
|
|
||||||
describe('Suspense', () => {
|
describe('Suspense', () => {
|
||||||
@ -30,7 +31,7 @@ describe('Suspense', () => {
|
|||||||
setup(props: any, { slots }: any) {
|
setup(props: any, { slots }: any) {
|
||||||
const p = new Promise(resolve => {
|
const p = new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve(() => h(comp, props, slots))
|
resolve(() => h<Component>(comp, props, slots))
|
||||||
}, delay)
|
}, delay)
|
||||||
})
|
})
|
||||||
// in Node 12, due to timer/nextTick mechanism change, we have to wait
|
// in Node 12, due to timer/nextTick mechanism change, we have to wait
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
ComponentOptionsWithArrayProps,
|
ComponentOptionsWithArrayProps,
|
||||||
ComponentOptionsWithObjectProps
|
ComponentOptionsWithObjectProps
|
||||||
} from './componentOptions'
|
} from './componentOptions'
|
||||||
import { SetupContext, RenderFunction } from './component'
|
import { SetupContext, RenderFunction, FunctionalComponent } from './component'
|
||||||
import { ComponentPublicInstance } from './componentProxy'
|
import { ComponentPublicInstance } from './componentProxy'
|
||||||
import { ExtractPropTypes, ComponentPropsOptions } from './componentProps'
|
import { ExtractPropTypes, ComponentPropsOptions } from './componentProps'
|
||||||
import { EmitsOptions } from './componentEmits'
|
import { EmitsOptions } from './componentEmits'
|
||||||
@ -34,7 +34,7 @@ export function defineComponent<Props, RawBindings = object>(
|
|||||||
// public props
|
// public props
|
||||||
VNodeProps & Props
|
VNodeProps & Props
|
||||||
>
|
>
|
||||||
}
|
} & FunctionalComponent<Props>
|
||||||
|
|
||||||
// overload 2: object format with no props
|
// overload 2: object format with no props
|
||||||
// (uses user defined props interface)
|
// (uses user defined props interface)
|
||||||
@ -59,7 +59,7 @@ export function defineComponent<
|
|||||||
E,
|
E,
|
||||||
VNodeProps & Props
|
VNodeProps & Props
|
||||||
>
|
>
|
||||||
}
|
} & ComponentOptionsWithoutProps<Props, RawBindings, D, C, M, E, EE>
|
||||||
|
|
||||||
// overload 3: object format with array props declaration
|
// overload 3: object format with array props declaration
|
||||||
// props inferred as { [key in PropNames]?: any }
|
// props inferred as { [key in PropNames]?: any }
|
||||||
@ -85,7 +85,7 @@ export function defineComponent<
|
|||||||
): {
|
): {
|
||||||
// array props technically doesn't place any contraints on props in TSX
|
// array props technically doesn't place any contraints on props in TSX
|
||||||
new (): ComponentPublicInstance<VNodeProps, RawBindings, D, C, M, E>
|
new (): ComponentPublicInstance<VNodeProps, RawBindings, D, C, M, E>
|
||||||
}
|
} & ComponentOptionsWithArrayProps<PropNames, RawBindings, D, C, M, E, EE>
|
||||||
|
|
||||||
// overload 4: object format with object props declaration
|
// overload 4: object format with object props declaration
|
||||||
// see `ExtractPropTypes` in ./componentProps.ts
|
// see `ExtractPropTypes` in ./componentProps.ts
|
||||||
@ -119,7 +119,7 @@ export function defineComponent<
|
|||||||
E,
|
E,
|
||||||
VNodeProps & ExtractPropTypes<PropsOptions, false>
|
VNodeProps & ExtractPropTypes<PropsOptions, false>
|
||||||
>
|
>
|
||||||
}
|
} & ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, E, EE>
|
||||||
|
|
||||||
// implementation, close to no-op
|
// implementation, close to no-op
|
||||||
export function defineComponent(options: unknown) {
|
export function defineComponent(options: unknown) {
|
||||||
|
@ -67,6 +67,11 @@ interface Constructor<P = any> {
|
|||||||
new (): { $props: P }
|
new (): { $props: P }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Excludes Component type from returned `defineComponent`
|
||||||
|
type NotDefinedComponent<T extends Component> = T extends Constructor
|
||||||
|
? never
|
||||||
|
: T
|
||||||
|
|
||||||
// The following is a series of overloads for providing props validation of
|
// The following is a series of overloads for providing props validation of
|
||||||
// manually written render functions.
|
// manually written render functions.
|
||||||
|
|
||||||
@ -110,8 +115,10 @@ export function h<P>(
|
|||||||
|
|
||||||
// catch-all for generic component types
|
// catch-all for generic component types
|
||||||
export function h(type: Component, children?: RawChildren): VNode
|
export function h(type: Component, children?: RawChildren): VNode
|
||||||
export function h(
|
|
||||||
type: ComponentOptions | FunctionalComponent<{}>,
|
// exclude `defineComponent`
|
||||||
|
export function h<Options extends ComponentOptions | FunctionalComponent<{}>>(
|
||||||
|
type: NotDefinedComponent<Options>,
|
||||||
props?: RawProps | null,
|
props?: RawProps | null,
|
||||||
children?: RawChildren | RawSlots
|
children?: RawChildren | RawSlots
|
||||||
): VNode
|
): VNode
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { expectError } from 'tsd'
|
import { expectError, expectAssignable } from 'tsd'
|
||||||
import {
|
import {
|
||||||
describe,
|
describe,
|
||||||
h,
|
h,
|
||||||
@ -131,3 +131,34 @@ describe('h support for generic component type', () => {
|
|||||||
}
|
}
|
||||||
foo({})
|
foo({})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #993
|
||||||
|
describe('describeComponent extends Component', () => {
|
||||||
|
// functional
|
||||||
|
expectAssignable<Component>(
|
||||||
|
defineComponent((_props: { foo?: string; bar: number }) => {})
|
||||||
|
)
|
||||||
|
|
||||||
|
// typed props
|
||||||
|
expectAssignable<Component>(defineComponent({}))
|
||||||
|
|
||||||
|
// prop arrays
|
||||||
|
expectAssignable<Component>(
|
||||||
|
defineComponent({
|
||||||
|
props: ['a', 'b']
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// prop object
|
||||||
|
expectAssignable<Component>(
|
||||||
|
defineComponent({
|
||||||
|
props: {
|
||||||
|
foo: String,
|
||||||
|
bar: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user