ComputedOptions,
MethodOptions
} from './apiOptions'
-import { UnwrapRef, ReactiveEffect, isRef, isReactive } from '@vue/reactivity'
+import {
+ ReactiveEffect,
+ isRef,
+ isReactive,
+ Ref,
+ ComputedRef
+} from '@vue/reactivity'
import { warn } from './warning'
import { Slots } from './componentSlots'
import {
// public properties exposed on the proxy, which is used as the render context
// in templates (as `this` in the render option)
export type ComponentPublicInstance<
- P = {},
- B = {},
- D = {},
+ P = {}, // props type extracted from props option
+ B = {}, // raw bindings returned from setup()
+ D = {}, // return from data()
C extends ComputedOptions = {},
M extends MethodOptions = {},
PublicProps = P
$nextTick: typeof nextTick
$watch: typeof instanceWatch
} & P &
- UnwrapRef<B> &
+ UnwrapSetupBindings<B> &
D &
ExtractComputedReturns<C> &
M
+type UnwrapSetupBindings<B> = { [K in keyof B]: UnwrapBinding<B[K]> }
+
+type UnwrapBinding<B> = B extends ComputedRef<any>
+ ? B extends ComputedRef<infer V> ? V : B
+ : B extends Ref<infer V> ? V : B
+
const publicPropertiesMap: Record<
string,
(i: ComponentInternalInstance) => any
import { expectError, expectType } from 'tsd'
-import { describe, defineComponent, PropType, ref, createApp } from './index'
+import {
+ describe,
+ defineComponent,
+ PropType,
+ ref,
+ Ref,
+ reactive,
+ createApp
+} from './index'
describe('with object props', () => {
interface ExpectedProps {
// setup context
return {
c: ref(1),
- d: {
+ d: reactive({
e: ref('hi')
- },
- f: {
+ }),
+ f: reactive({
g: ref('hello' as GT)
+ }),
+ h: {
+ i: ref('hi')
}
}
},
expectType<string>(this.d.e)
expectType<GT>(this.f.g)
+ // should not unwrap refs nested under non-reactive objects
+ expectType<Ref<string>>(this.h.i)
+
// setup context properties should be mutable
this.c = 2