Skip to content

Commit 24fcf6a

Browse files
authored
fix(types): properly infer return type from async setup (#2051)
fix #2049
1 parent 0124eac commit 24fcf6a

File tree

4 files changed

+47
-7
lines changed

4 files changed

+47
-7
lines changed

packages/runtime-core/src/apiDefineComponent.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
ComponentOptionsWithArrayProps,
66
ComponentOptionsWithObjectProps,
77
ComponentOptionsMixin,
8-
RenderFunction
8+
RenderFunction,
9+
UnwrapAsyncBindings
910
} from './componentOptions'
1011
import {
1112
SetupContext,
@@ -37,7 +38,7 @@ export function defineComponent<Props, RawBindings = object>(
3738
): ComponentPublicInstanceConstructor<
3839
CreateComponentPublicInstance<
3940
Props,
40-
RawBindings,
41+
UnwrapAsyncBindings<RawBindings>,
4142
{},
4243
{},
4344
{},
@@ -78,7 +79,7 @@ export function defineComponent<
7879
): ComponentPublicInstanceConstructor<
7980
CreateComponentPublicInstance<
8081
Props,
81-
RawBindings,
82+
UnwrapAsyncBindings<RawBindings>,
8283
D,
8384
C,
8485
M,
@@ -130,7 +131,7 @@ export function defineComponent<
130131
// but now we can export array props in TSX
131132
CreateComponentPublicInstance<
132133
Readonly<{ [key in PropNames]?: any }>,
133-
RawBindings,
134+
UnwrapAsyncBindings<RawBindings>,
134135
D,
135136
C,
136137
M,
@@ -181,7 +182,7 @@ export function defineComponent<
181182
): ComponentPublicInstanceConstructor<
182183
CreateComponentPublicInstance<
183184
ExtractPropTypes<PropsOptions, false>,
184-
RawBindings,
185+
UnwrapAsyncBindings<RawBindings>,
185186
D,
186187
C,
187188
M,

packages/runtime-core/src/componentOptions.ts

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export interface ComponentCustomOptions {}
7272

7373
export type RenderFunction = () => VNodeChild
7474

75+
export type UnwrapAsyncBindings<T> = T extends Promise<infer S> ? S : T
76+
7577
export interface ComponentOptionsBase<
7678
Props,
7779
RawBindings,

packages/runtime-core/src/componentPublicInstance.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import {
2727
OptionTypesType,
2828
OptionTypesKeys,
2929
resolveMergedOptions,
30-
isInBeforeCreate
30+
isInBeforeCreate,
31+
UnwrapAsyncBindings
3132
} from './componentOptions'
3233
import { EmitsOptions, EmitFn } from './componentEmits'
3334
import { Slots } from './componentSlots'
@@ -168,7 +169,7 @@ export type ComponentPublicInstance<
168169
options?: WatchOptions
169170
): WatchStopHandle
170171
} & P &
171-
ShallowUnwrapRef<B> &
172+
ShallowUnwrapRef<UnwrapAsyncBindings<B>> &
172173
D &
173174
ExtractComputedReturns<C> &
174175
M &

test-dts/defineComponent.test-d.tsx

+36
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,39 @@ describe('extract instance type', () => {
864864
// @ts-expect-error
865865
expectError((compA.baseA = 1))
866866
})
867+
868+
describe('async setup', () => {
869+
type GT = string & { __brand: unknown }
870+
const Comp = defineComponent({
871+
async setup() {
872+
// setup context
873+
return {
874+
a: ref(1),
875+
b: {
876+
c: ref('hi')
877+
},
878+
d: reactive({
879+
e: ref('hello' as GT)
880+
})
881+
}
882+
},
883+
render() {
884+
// assert setup context unwrapping
885+
expectType<number>(this.a)
886+
expectType<string>(this.b.c.value)
887+
expectType<GT>(this.d.e)
888+
889+
// setup context properties should be mutable
890+
this.a = 2
891+
}
892+
})
893+
894+
const vm = {} as InstanceType<typeof Comp>
895+
// assert setup context unwrapping
896+
expectType<number>(vm.a)
897+
expectType<string>(vm.b.c.value)
898+
expectType<GT>(vm.d.e)
899+
900+
// setup context properties should be mutable
901+
vm.a = 2
902+
})

0 commit comments

Comments
 (0)