From 05679551eb0941d44430d6941826e9d4ad5d1833 Mon Sep 17 00:00:00 2001 From: rudy-xhd Date: Tue, 13 Dec 2022 23:36:34 +0800 Subject: [PATCH] fix(types): props type is incompatible with setup returned type --- .../runtime-core/src/apiDefineComponent.ts | 3 +- .../src/componentPublicInstance.ts | 6 +-- test-dts/defineComponent.test-d.tsx | 38 +++++++++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index c10ac74e4a9..2a460a9320f 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -62,8 +62,7 @@ export type DefineComponent< PP & Props, Defaults, true - > & - Props + > > & ComponentOptionsBase< Props, diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 695df45898a..5c77b01b05c 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -14,7 +14,8 @@ import { extend, isString, isFunction, - UnionToIntersection + UnionToIntersection, + IfAny } from '@vue/shared' import { toRaw, @@ -167,7 +168,6 @@ export type CreateComponentPublicInstance< ComponentOptionsBase, I > - // public properties exposed on the proxy, which is used as the render context // in templates (as `this` in the render option) export type ComponentPublicInstance< @@ -205,7 +205,7 @@ export type ComponentPublicInstance< : (...args: any) => any, options?: WatchOptions ): WatchStopHandle -} & P & +} & IfAny>> & ShallowUnwrapRef & UnwrapNestedRefs & ExtractComputedReturns & diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 208501e4286..7847b86abae 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -1041,13 +1041,13 @@ describe('inject', () => { }, inject: { foo: 'foo', - bar: 'bar', + bar: 'bar' }, created() { expectType(this.foo) expectType(this.bar) // @ts-expect-error - expectError(this.foobar = 1) + expectError((this.foobar = 1)) } }) @@ -1059,7 +1059,7 @@ describe('inject', () => { expectType(this.foo) expectType(this.bar) // @ts-expect-error - expectError(this.foobar = 1) + expectError((this.foobar = 1)) } }) @@ -1073,13 +1073,13 @@ describe('inject', () => { bar: { from: 'pbar', default: 'bar' - }, + } }, created() { expectType(this.foo) expectType(this.bar) // @ts-expect-error - expectError(this.foobar = 1) + expectError((this.foobar = 1)) } }) @@ -1088,9 +1088,9 @@ describe('inject', () => { props: ['a', 'b'], created() { // @ts-expect-error - expectError(this.foo = 1) + expectError((this.foo = 1)) // @ts-expect-error - expectError(this.bar = 1) + expectError((this.bar = 1)) } }) }) @@ -1257,6 +1257,30 @@ describe('prop starting with `on*` is broken', () => { }) }) +describe('should work when props type is incompatible with setup returned type ', () => { + type SizeType = 'small' | 'big' + const Comp = defineComponent({ + props: { + size: { + type: String as PropType, + required: true + } + }, + setup(props) { + expectType(props.size) + return { + size: 1 + } + } + }) + type CompInstance = InstanceType + + const CompA = {} as CompInstance + expectType(CompA) + expectType(CompA.size) + expectType(CompA.$props.size) +}) + // check if defineComponent can be exported export default { // function components