From c64f71e39c0dfce8d16d3563784feb95681a3742 Mon Sep 17 00:00:00 2001 From: pikax Date: Mon, 18 Jan 2021 16:51:14 +0000 Subject: [PATCH 1/3] types(defineComponent): support passing Prop interface to defineComponent --- .../runtime-core/src/apiDefineComponent.ts | 34 ++++++++++++++++++- test-dts/defineComponent.test-d.tsx | 28 +++++++++++++++ test-dts/tsx.test-d.tsx | 18 +++++++++- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 333d18a30f3..ef0c7f97aea 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -16,7 +16,8 @@ import { import { ExtractPropTypes, ComponentPropsOptions, - ExtractDefaultPropTypes + ExtractDefaultPropTypes, + Prop } from './componentProps' import { EmitsOptions } from './componentEmits' import { isFunction } from '@vue/shared' @@ -26,6 +27,12 @@ import { ComponentPublicInstanceConstructor } from './componentPublicInstance' +export type PropObjectTyped> = { + [K in keyof T]: undefined extends T[K] + ? Prop + : Prop & { required: true } +} + export type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps @@ -179,6 +186,31 @@ export function defineComponent< > ): DefineComponent +export function defineComponent< + Props extends Record, + RawBindings = {}, + D = {}, + C extends ComputedOptions = {}, + M extends MethodOptions = {}, + Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, + Extends extends ComponentOptionsMixin = ComponentOptionsMixin, + E extends EmitsOptions = Record, + EE extends string = string, + PropOptions extends PropObjectTyped = PropObjectTyped +>( + options: ComponentOptionsWithObjectProps< + PropOptions, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE + > +): DefineComponent + // implementation, close to no-op export function defineComponent(options: unknown) { return isFunction(options) ? { setup: options, name: options.name } : options diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index e28a82e1d37..88915ee4b1a 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -960,6 +960,34 @@ describe('async setup', () => { vm.a = 2 }) +// type is correct +defineComponent<{ a?: string }>({ + props: { + a: String + }, + + setup(props) { + props.a + } +}) + +// error type is incorrect + +//@ts-expect-error invalid type on the prop definition +defineComponent<{ a: number }>({ + props: { + a: { + type: String, + required: true + } + }, + + // @ts-expect-error cannot resolve props type because of the mismatch + setup(props) { + props.a + } +}) + // check if defineComponent can be exported export default { // function components diff --git a/test-dts/tsx.test-d.tsx b/test-dts/tsx.test-d.tsx index 43a2464b859..83959dce256 100644 --- a/test-dts/tsx.test-d.tsx +++ b/test-dts/tsx.test-d.tsx @@ -5,7 +5,8 @@ import { Fragment, Teleport, expectError, - expectType + expectType, + defineComponent } from './index' expectType(
) @@ -54,3 +55,18 @@ expectType( ) // @ts-expect-error expectError() + +const Comp = defineComponent({ + props: { + msg: String + }, + setup(props) { + return () =>
{props.msg}
+ } +}) + +const Other = defineComponent({ + setup() { + return () => + } +}) From 441c181d6d8f3472e112c798adf30162f602e93b Mon Sep 17 00:00:00 2001 From: pikax Date: Mon, 18 Jan 2021 16:59:27 +0000 Subject: [PATCH 2/3] chore: add comment to overload and remove code --- packages/runtime-core/src/apiDefineComponent.ts | 2 ++ test-dts/tsx.test-d.tsx | 15 --------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index ef0c7f97aea..8bfe814be25 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -186,6 +186,8 @@ export function defineComponent< > ): DefineComponent +// overload 5: Props interface passed as argument +// see `ExtractPropTypes` in ./componentProps.ts export function defineComponent< Props extends Record, RawBindings = {}, diff --git a/test-dts/tsx.test-d.tsx b/test-dts/tsx.test-d.tsx index 83959dce256..6f076622695 100644 --- a/test-dts/tsx.test-d.tsx +++ b/test-dts/tsx.test-d.tsx @@ -55,18 +55,3 @@ expectType( ) // @ts-expect-error expectError() - -const Comp = defineComponent({ - props: { - msg: String - }, - setup(props) { - return () =>
{props.msg}
- } -}) - -const Other = defineComponent({ - setup() { - return () => - } -}) From 6140351ce9ad6de3bbc1844ce554da4bcd04c6e1 Mon Sep 17 00:00:00 2001 From: pikax Date: Mon, 18 Jan 2021 17:07:29 +0000 Subject: [PATCH 3/3] chore: remove unused improt --- test-dts/tsx.test-d.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test-dts/tsx.test-d.tsx b/test-dts/tsx.test-d.tsx index 6f076622695..43a2464b859 100644 --- a/test-dts/tsx.test-d.tsx +++ b/test-dts/tsx.test-d.tsx @@ -5,8 +5,7 @@ import { Fragment, Teleport, expectError, - expectType, - defineComponent + expectType } from './index' expectType(
)