diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index f9de525c87d..61f968b7634 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -39,7 +39,14 @@ interface PropOptions { export type PropType = PropConstructor | PropConstructor[] -type PropConstructor = { new (...args: any[]): T & object } | { (): T } +type PropConstructor = + | { new (...args: any[]): T & object } + | { (): T } + | PropMethod + +type PropMethod = T extends (...args: any) => any // if is function with args + ? { new (): T; (): T; readonly proptotype: Function } // Create Function like contructor + : never type RequiredKeys = { [K in keyof T]: T[K] extends diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 33f55695569..35ae4e6d65f 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -12,11 +12,16 @@ describe('with object props', () => { interface ExpectedProps { a?: number | undefined b: string + e?: Function bb: string cc?: string[] | undefined dd: string[] + ee?: () => string + ff?: (a: number, b: string) => { a: boolean } ccc?: string[] | undefined ddd: string[] + eee: () => { a: string } + fff: (a: number, b: string) => { a: boolean } } type GT = string & { __brand: unknown } @@ -29,6 +34,7 @@ describe('with object props', () => { type: String, required: true }, + e: Function, // default value should infer type and make it non-void bb: { default: 'hello' @@ -40,23 +46,42 @@ describe('with object props', () => { type: Array as PropType, required: true }, + // return type + ee: Function as PropType<() => string>, + // arguments + object return + ff: Function as PropType<(a: number, b: string) => { a: boolean }>, // explicit type casting with constructor ccc: Array as () => string[], // required + contructor type casting ddd: { type: Array as () => string[], required: true + }, + // required + object return + eee: { + type: Function as PropType<() => { a: string }>, + required: true + }, + // required + arguments + object return + fff: { + type: Function as PropType<(a: number, b: string) => { a: boolean }>, + required: true } }, setup(props) { // type assertion. See https://github.com/SamVerschueren/tsd expectType(props.a) expectType(props.b) + expectType(props.e) expectType(props.bb) expectType(props.cc) expectType(props.dd) + expectType(props.ee) + expectType(props.ff) expectType(props.ccc) expectType(props.ddd) + expectType(props.eee) + expectType(props.fff) // props should be readonly expectError((props.a = 1))