types: mixin and extends typing on data and setup (#2404)

close #2350
This commit is contained in:
Carlos Rodrigues 2020-12-04 21:06:34 +00:00 committed by GitHub
parent 0af8c8d972
commit 6684c6334d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 3 deletions

View File

@ -59,6 +59,7 @@ import {
import { warn } from './warning'
import { VNodeChild } from './vnode'
import { callWithAsyncErrorHandling } from './errorHandling'
import { UnionToIntersection } from './helpers/typeUtils'
/**
* Interface for declaring custom options.
@ -80,6 +81,19 @@ export interface ComponentCustomOptions {}
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,
@ -97,7 +111,9 @@ export interface ComponentOptionsBase<
ComponentCustomOptions {
setup?: (
this: void,
props: Props,
props: Props &
UnionToIntersection<ExtractOptionProp<Mixin>> &
UnionToIntersection<ExtractOptionProp<Extends>>,
ctx: SetupContext<E>
) => Promise<RawBindings> | RawBindings | RenderFunction | void
name?: string
@ -358,8 +374,24 @@ interface LegacyOptions<
// 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
@ -590,6 +622,7 @@ export function applyOptions(
deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis))
}
if (dataOptions) {
// @ts-ignore dataOptions is not fully type safe
resolveData(instance, dataOptions, publicThis)
}
if (__DEV__) {

View File

@ -445,10 +445,18 @@ describe('with mixins', () => {
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
@ -467,6 +475,34 @@ describe('with mixins', () => {
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