diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index eda62eaab..c054e65a8 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -5,7 +5,8 @@ import { ComponentOptionsWithArrayProps, ComponentOptionsWithObjectProps, ComponentOptionsMixin, - RenderFunction + RenderFunction, + UnwrapAsyncBindings } from './componentOptions' import { SetupContext, @@ -37,7 +38,7 @@ export function defineComponent( ): ComponentPublicInstanceConstructor< CreateComponentPublicInstance< Props, - RawBindings, + UnwrapAsyncBindings, {}, {}, {}, @@ -78,7 +79,7 @@ export function defineComponent< ): ComponentPublicInstanceConstructor< CreateComponentPublicInstance< Props, - RawBindings, + UnwrapAsyncBindings, D, C, M, @@ -130,7 +131,7 @@ export function defineComponent< // but now we can export array props in TSX CreateComponentPublicInstance< Readonly<{ [key in PropNames]?: any }>, - RawBindings, + UnwrapAsyncBindings, D, C, M, @@ -181,7 +182,7 @@ export function defineComponent< ): ComponentPublicInstanceConstructor< CreateComponentPublicInstance< ExtractPropTypes, - RawBindings, + UnwrapAsyncBindings, D, C, M, diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 0eb24a6c2..d02a1bb0b 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -72,6 +72,8 @@ export interface ComponentCustomOptions {} export type RenderFunction = () => VNodeChild +export type UnwrapAsyncBindings = T extends Promise ? S : T + export interface ComponentOptionsBase< Props, RawBindings, diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 695e5ace3..77fcbeeae 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -27,7 +27,8 @@ import { OptionTypesType, OptionTypesKeys, resolveMergedOptions, - isInBeforeCreate + isInBeforeCreate, + UnwrapAsyncBindings } from './componentOptions' import { EmitsOptions, EmitFn } from './componentEmits' import { Slots } from './componentSlots' @@ -168,7 +169,7 @@ export type ComponentPublicInstance< options?: WatchOptions ): WatchStopHandle } & P & - ShallowUnwrapRef & + ShallowUnwrapRef> & D & ExtractComputedReturns & M & diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 18c3338ab..59d6a3bcb 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -864,3 +864,39 @@ describe('extract instance type', () => { // @ts-expect-error expectError((compA.baseA = 1)) }) + +describe('async setup', () => { + type GT = string & { __brand: unknown } + const Comp = defineComponent({ + async setup() { + // setup context + return { + a: ref(1), + b: { + c: ref('hi') + }, + d: reactive({ + e: ref('hello' as GT) + }) + } + }, + render() { + // assert setup context unwrapping + expectType(this.a) + expectType(this.b.c.value) + expectType(this.d.e) + + // setup context properties should be mutable + this.a = 2 + } + }) + + const vm = {} as InstanceType + // assert setup context unwrapping + expectType(vm.a) + expectType(vm.b.c.value) + expectType(vm.d.e) + + // setup context properties should be mutable + vm.a = 2 +})