import { warn } from './warning'
import { VNodeChild } from './vnode'
import { callWithAsyncErrorHandling } from './errorHandling'
+import { UnionToIntersection } from './helpers/typeUtils'
/**
* Interface for declaring custom options.
export type RenderFunction = () => VNodeChild
+type ExtractOptionProp<T> = T extends ComponentOptionsBase<
+ infer P,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any
+>
+ ? unknown extends P ? {} : P
+ : {}
+
export interface ComponentOptionsBase<
Props,
RawBindings,
ComponentCustomOptions {
setup?: (
this: void,
- props: Props,
+ props: Props &
+ UnionToIntersection<ExtractOptionProp<Mixin>> &
+ UnionToIntersection<ExtractOptionProp<Extends>>,
ctx: SetupContext<E>
) => Promise<RawBindings> | RawBindings | RenderFunction | void
name?: string
// since that leads to some sort of circular inference and breaks ThisType
// for the entire component.
data?: (
- this: CreateComponentPublicInstance<Props>,
- vm: CreateComponentPublicInstance<Props>
+ this: CreateComponentPublicInstance<
+ Props,
+ {},
+ {},
+ {},
+ MethodOptions,
+ Mixin,
+ Extends
+ >,
+ vm: CreateComponentPublicInstance<
+ Props,
+ {},
+ {},
+ {},
+ MethodOptions,
+ Mixin,
+ Extends
+ >
) => D
computed?: C
methods?: M
deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis))
}
if (dataOptions) {
+ // @ts-ignore dataOptions is not fully type safe
resolveData(instance, dataOptions, publicThis)
}
if (__DEV__) {
const MixinD = defineComponent({
mixins: [MixinA],
data() {
+ //@ts-expect-error computed are not available on data()
+ expectError<number>(this.dC1)
+ //@ts-expect-error computed are not available on data()
+ expectError<string>(this.dC2)
+
return {
d: 4
}
},
+ setup(props) {
+ expectType<string>(props.aP1)
+ },
computed: {
dC1(): number {
return this.d + this.a
required: true
}
},
+
+ data(vm) {
+ expectType<number>(vm.a)
+ expectType<number>(vm.b)
+ expectType<number>(vm.c)
+ expectType<number>(vm.d)
+
+ // should also expose declared props on `this`
+ expectType<number>(this.a)
+ expectType<string>(this.aP1)
+ expectType<boolean | undefined>(this.aP2)
+ expectType<number>(this.b)
+ expectType<any>(this.bP1)
+ expectType<number>(this.c)
+ expectType<number>(this.d)
+
+ return {}
+ },
+
+ setup(props) {
+ expectType<string>(props.z)
+ // props
+ expectType<string>(props.aP1)
+ expectType<boolean | undefined>(props.aP2)
+ expectType<any>(props.bP1)
+ expectType<any>(props.bP2)
+ expectType<string>(props.z)
+ },
render() {
const props = this.$props
// props