feat(types): support mixins inference for new Vue() (#12737)

close #12730
This commit is contained in:
gu 2022-08-18 15:56:37 +08:00 committed by GitHub
parent b4bf4c52ad
commit 89a6b5e865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 166 additions and 34 deletions

33
types/options.d.ts vendored
View File

@ -3,6 +3,7 @@ import { VNode, VNodeData, VNodeDirective, NormalizedScopedSlot } from './vnode'
import { SetupContext } from './v3-setup-context'
import { DebuggerEvent } from './v3-generated'
import { DefineComponent } from './v3-define-component'
import { ComponentOptionsMixin } from './v3-component-options'
type Constructor = {
new (...args: any[]): any
@ -93,7 +94,9 @@ export type ThisTypedComponentOptionsWithArrayProps<
Methods,
Computed,
PropNames extends string,
SetupBindings
SetupBindings,
Mixin,
Extends
> = object &
ComponentOptions<
V,
@ -102,7 +105,9 @@ export type ThisTypedComponentOptionsWithArrayProps<
Computed,
PropNames[],
Record<PropNames, any>,
SetupBindings
SetupBindings,
Mixin,
Extends
> &
ThisType<
CombinedVueInstance<
@ -111,7 +116,9 @@ export type ThisTypedComponentOptionsWithArrayProps<
Methods,
Computed,
Readonly<Record<PropNames, any>>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
>
@ -124,7 +131,9 @@ export type ThisTypedComponentOptionsWithRecordProps<
Methods,
Computed,
Props,
SetupBindings
SetupBindings,
Mixin,
Extends
> = object &
ComponentOptions<
V,
@ -133,7 +142,9 @@ export type ThisTypedComponentOptionsWithRecordProps<
Computed,
RecordPropsDefinition<Props>,
Props,
SetupBindings
SetupBindings,
Mixin,
Extends
> &
ThisType<
CombinedVueInstance<
@ -142,7 +153,9 @@ export type ThisTypedComponentOptionsWithRecordProps<
Methods,
Computed,
Readonly<Props>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
>
@ -158,7 +171,9 @@ export interface ComponentOptions<
Computed = DefaultComputed,
PropsDef = PropsDefinition<DefaultProps>,
Props = DefaultProps,
RawBindings = {}
RawBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
> {
data?: Data
props?: PropsDef
@ -217,12 +232,12 @@ export interface ComponentOptions<
}
parent?: Vue
mixins?: (ComponentOptions<Vue> | typeof Vue)[]
mixins?: (Mixin | ComponentOptions<Vue> | typeof Vue)[]
name?: string
// for SFC auto name inference w/ ts-loader check
__name?: string
// TODO: support properly inferred 'extends'
extends?: ComponentOptions<Vue> | typeof Vue
extends?: Extends | ComponentOptions<Vue> | typeof Vue
delimiters?: [string, string]
comments?: boolean
inheritAttrs?: boolean

View File

@ -1,4 +1,4 @@
import Vue, { VNode } from '../index'
import Vue, { VNode, defineComponent } from '../index'
import { ComponentOptions } from '../options'
class Test extends Vue {
@ -246,3 +246,40 @@ const ComponentWithStyleInVNodeData = Vue.extend({
])
}
})
// infer mixin type with new Vue() #12730
new Vue({
mixins: [
defineComponent({
props: {
p1: String,
p2: {
type: Number,
default: 0
}
},
data() {
return {
foo: 123
}
},
computed: {
bar() {
return 123
}
}
}),
{
methods: {
hello(n: number) {}
}
}
],
created() {
this.hello(this.foo)
this.hello(this.bar)
// @ts-expect-error
this.hello(this.p1)
this.hello(this.p2)
}
})

View File

@ -79,11 +79,11 @@ type ExtractMixin<T> = {
Mixin: MixinToOptionTypes<T>
}[T extends ComponentOptionsMixin ? 'Mixin' : never]
type IntersectionMixin<T> = IsDefaultMixinComponent<T> extends true
export type IntersectionMixin<T> = IsDefaultMixinComponent<T> extends true
? OptionTypesType<{}, {}, {}, {}, {}, {}>
: UnionToIntersection<ExtractMixin<T>>
type UnwrapMixinsType<
export type UnwrapMixinsType<
T,
Type extends OptionTypesKeys
> = T extends OptionTypesType ? T[Type] : never

124
types/vue.d.ts vendored
View File

@ -13,7 +13,15 @@ import {
import { VNode, VNodeData, VNodeChildren, NormalizedScopedSlot } from './vnode'
import { PluginFunction, PluginObject } from './plugin'
import { DefineComponent } from './v3-define-component'
import { nextTick } from './v3-generated'
import { nextTick, UnwrapNestedRefs, ShallowUnwrapRef } from './v3-generated'
import {
UnwrapMixinsType,
IntersectionMixin
} from './v3-component-public-instance'
import {
ExtractComputedReturns,
ComponentOptionsMixin
} from './v3-component-options'
export interface CreateElement {
(
@ -100,12 +108,20 @@ export type CombinedVueInstance<
Methods,
Computed,
Props,
SetupBindings = {}
> = Data &
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>
> = UnwrapNestedRefs<UnwrapMixinsType<PublicMixin, 'D'>> &
Data &
UnwrapMixinsType<PublicMixin, 'M'> &
Methods &
ExtractComputedReturns<UnwrapMixinsType<PublicMixin, 'C'>> &
Computed &
UnwrapMixinsType<PublicMixin, 'P'> &
Props &
Instance &
ShallowUnwrapRef<UnwrapMixinsType<PublicMixin, 'B'>> &
(SetupBindings extends void ? {} : SetupBindings)
export type ExtendedVue<
@ -114,9 +130,20 @@ export type ExtendedVue<
Methods,
Computed,
Props,
SetupBindings = {}
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
> = VueConstructor<
CombinedVueInstance<Instance, Data, Methods, Computed, Props, SetupBindings> &
CombinedVueInstance<
Instance,
Data,
Methods,
Computed,
Props,
SetupBindings,
Mixin,
Extends
> &
Vue
>
@ -142,7 +169,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods = object,
Computed = object,
PropNames extends string = never,
SetupBindings = {}
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
options?: ThisTypedComponentOptionsWithArrayProps<
V,
@ -150,7 +179,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
PropNames,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): CombinedVueInstance<
V,
@ -158,7 +189,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
/**
@ -172,7 +205,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods = object,
Computed = object,
Props = object,
SetupBindings = {}
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
options?: ThisTypedComponentOptionsWithRecordProps<
V,
@ -180,7 +215,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Props,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): CombinedVueInstance<
V,
@ -188,7 +225,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Record<keyof Props, any>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
/**
@ -211,7 +250,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
PropNames extends string = never,
SetupBindings = {}
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
options?: ThisTypedComponentOptionsWithArrayProps<
V,
@ -219,7 +260,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
PropNames,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): ExtendedVue<
V,
@ -227,22 +270,43 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
/**
* extend with object props
*/
extend<Data, Methods, Computed, Props, SetupBindings = {}>(
extend<
Data,
Methods,
Computed,
Props,
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
options?: ThisTypedComponentOptionsWithRecordProps<
V,
Data,
Methods,
Computed,
Props,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): ExtendedVue<V, Data, Methods, Computed, Props, SetupBindings>
): ExtendedVue<
V,
Data,
Methods,
Computed,
Props,
SetupBindings,
Mixin,
Extends
>
/**
* extend with functional + array props
@ -287,7 +351,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
PropNames extends string = never,
SetupBindings = {}
SetupBindings = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
id: string,
definition?: ThisTypedComponentOptionsWithArrayProps<
@ -296,7 +362,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
PropNames,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): ExtendedVue<
V,
@ -304,9 +372,19 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
SetupBindings,
Mixin,
Extends
>
component<Data, Methods, Computed, Props, SetupBindings>(
component<
Data,
Methods,
Computed,
Props,
SetupBindings,
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
id: string,
definition?: ThisTypedComponentOptionsWithRecordProps<
V,
@ -314,7 +392,9 @@ export interface VueConstructor<V extends Vue = Vue> {
Methods,
Computed,
Props,
SetupBindings
SetupBindings,
Mixin,
Extends
>
): ExtendedVue<V, Data, Methods, Computed, Props, SetupBindings>
component<PropNames extends string>(