types: improve h() and TSX type inference
- Should allow extraneous props as attrs in TSX - Should check props when using constructor type returned by createComponent() in h()
This commit is contained in:
parent
b114cdf6ee
commit
3a6dcd3aba
@ -67,7 +67,14 @@ test('createComponent type inference', () => {
|
||||
}
|
||||
})
|
||||
// test TSX props inference
|
||||
;<MyComponent a={1} b="foo" dd={['foo']} ddd={['foo']} />
|
||||
;<MyComponent
|
||||
a={1}
|
||||
b="foo"
|
||||
dd={['foo']}
|
||||
ddd={['foo']}
|
||||
// should allow extraneous as attrs
|
||||
class="bar"
|
||||
/>
|
||||
})
|
||||
|
||||
test('type inference w/ optional props declaration', () => {
|
||||
|
@ -9,13 +9,31 @@ import { SetupContext, RenderFunction } from './component'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ExtractPropTypes } from './componentProps'
|
||||
import { isFunction } from '@vue/shared'
|
||||
import { Ref } from '@vue/reactivity'
|
||||
|
||||
interface BaseProps {
|
||||
[key: string]: any
|
||||
key?: string | number
|
||||
ref?: string | Ref | Function
|
||||
}
|
||||
|
||||
// overload 1: direct setup function
|
||||
// (uses user defined props interface)
|
||||
// __isConstructor: true is a type-only differentiator to avoid returned
|
||||
// constructor type from being matched as an options object in h()
|
||||
export function createComponent<Props, RawBindings = object>(
|
||||
setup: (props: Props, ctx: SetupContext) => RawBindings | RenderFunction
|
||||
): {
|
||||
new (): ComponentPublicInstance<Props, RawBindings>
|
||||
__isConstructor: true
|
||||
new (): ComponentPublicInstance<
|
||||
Props,
|
||||
RawBindings,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
// public props
|
||||
BaseProps & Props
|
||||
>
|
||||
}
|
||||
|
||||
// overload 2: object format with no props
|
||||
@ -30,11 +48,19 @@ export function createComponent<
|
||||
>(
|
||||
options: ComponentOptionsWithoutProps<Props, RawBindings, D, C, M>
|
||||
): {
|
||||
new (): ComponentPublicInstance<Props, RawBindings, D, C, M>
|
||||
__isConstructor: true
|
||||
new (): ComponentPublicInstance<
|
||||
Props,
|
||||
RawBindings,
|
||||
D,
|
||||
C,
|
||||
M,
|
||||
BaseProps & Props
|
||||
>
|
||||
}
|
||||
|
||||
// overload 3: object format with array props declaration
|
||||
// props inferred as { [key in PropNames]?: unknown }
|
||||
// props inferred as { [key in PropNames]?: any }
|
||||
// return type is for Vetur and TSX support
|
||||
export function createComponent<
|
||||
PropNames extends string,
|
||||
@ -45,13 +71,9 @@ export function createComponent<
|
||||
>(
|
||||
options: ComponentOptionsWithArrayProps<PropNames, RawBindings, D, C, M>
|
||||
): {
|
||||
new (): ComponentPublicInstance<
|
||||
{ [key in PropNames]?: unknown },
|
||||
RawBindings,
|
||||
D,
|
||||
C,
|
||||
M
|
||||
>
|
||||
__isConstructor: true
|
||||
// array props technically doesn't place any contraints on props in TSX
|
||||
new (): ComponentPublicInstance<BaseProps, RawBindings, D, C, M>
|
||||
}
|
||||
|
||||
// overload 4: object format with object props declaration
|
||||
@ -65,14 +87,15 @@ export function createComponent<
|
||||
>(
|
||||
options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M>
|
||||
): {
|
||||
__isConstructor: true
|
||||
// for Vetur and TSX support
|
||||
new (): ComponentPublicInstance<
|
||||
ExtractPropTypes<PropsOptions>,
|
||||
ExtractPropTypes<PropsOptions, false>,
|
||||
RawBindings,
|
||||
D,
|
||||
C,
|
||||
M,
|
||||
ExtractPropTypes<PropsOptions, false>
|
||||
BaseProps & ExtractPropTypes<PropsOptions, false>
|
||||
>
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,10 @@ export interface ComponentOptionsBase<
|
||||
components?: Record<string, Component>
|
||||
directives?: Record<string, Directive>
|
||||
inheritAttrs?: boolean
|
||||
|
||||
// type-only differentiator to separate OptionWihtoutProps from a constructor
|
||||
// type returned by createComponent()
|
||||
__isConstructor?: never
|
||||
}
|
||||
|
||||
export type ComponentOptionsWithoutProps<
|
||||
|
@ -133,9 +133,7 @@ export function h<P>(
|
||||
): VNode
|
||||
export function h<P extends string>(
|
||||
type: ComponentOptionsWithArrayProps<P>,
|
||||
// TODO for now this doesn't really do anything, but it would become useful
|
||||
// if we make props required by default
|
||||
props?: (RawProps & { [key in P]?: any }) | null,
|
||||
props?: RawProps | null,
|
||||
children?: RawChildren | RawSlots
|
||||
): VNode
|
||||
export function h<P>(
|
||||
|
Loading…
Reference in New Issue
Block a user