diff --git a/types/options.d.ts b/types/options.d.ts index e11020f4948..c82c6c5f8ae 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -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, - SetupBindings + SetupBindings, + Mixin, + Extends > & ThisType< CombinedVueInstance< @@ -111,7 +116,9 @@ export type ThisTypedComponentOptionsWithArrayProps< Methods, Computed, Readonly>, - 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, - SetupBindings + SetupBindings, + Mixin, + Extends > & ThisType< CombinedVueInstance< @@ -142,7 +153,9 @@ export type ThisTypedComponentOptionsWithRecordProps< Methods, Computed, Readonly, - SetupBindings + SetupBindings, + Mixin, + Extends > > @@ -158,7 +171,9 @@ export interface ComponentOptions< Computed = DefaultComputed, PropsDef = PropsDefinition, 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 | typeof Vue)[] + mixins?: (Mixin | ComponentOptions | typeof Vue)[] name?: string // for SFC auto name inference w/ ts-loader check __name?: string // TODO: support properly inferred 'extends' - extends?: ComponentOptions | typeof Vue + extends?: Extends | ComponentOptions | typeof Vue delimiters?: [string, string] comments?: boolean inheritAttrs?: boolean diff --git a/types/test/vue-test.ts b/types/test/vue-test.ts index 8489f3ae8ed..b792cec583d 100644 --- a/types/test/vue-test.ts +++ b/types/test/vue-test.ts @@ -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) + } +}) diff --git a/types/v3-component-public-instance.d.ts b/types/v3-component-public-instance.d.ts index 3586f4031e8..1c55908ac73 100644 --- a/types/v3-component-public-instance.d.ts +++ b/types/v3-component-public-instance.d.ts @@ -79,11 +79,11 @@ type ExtractMixin = { Mixin: MixinToOptionTypes }[T extends ComponentOptionsMixin ? 'Mixin' : never] -type IntersectionMixin = IsDefaultMixinComponent extends true +export type IntersectionMixin = IsDefaultMixinComponent extends true ? OptionTypesType<{}, {}, {}, {}, {}, {}> : UnionToIntersection> -type UnwrapMixinsType< +export type UnwrapMixinsType< T, Type extends OptionTypesKeys > = T extends OptionTypesType ? T[Type] : never diff --git a/types/vue.d.ts b/types/vue.d.ts index 8c91bc88a2f..5a2027a0179 100644 --- a/types/vue.d.ts +++ b/types/vue.d.ts @@ -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 & IntersectionMixin +> = UnwrapNestedRefs> & + Data & + UnwrapMixinsType & Methods & + ExtractComputedReturns> & Computed & + UnwrapMixinsType & Props & Instance & + ShallowUnwrapRef> & (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 & + CombinedVueInstance< + Instance, + Data, + Methods, + Computed, + Props, + SetupBindings, + Mixin, + Extends + > & Vue > @@ -142,7 +169,9 @@ export interface VueConstructor { 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 { Methods, Computed, PropNames, - SetupBindings + SetupBindings, + Mixin, + Extends > ): CombinedVueInstance< V, @@ -158,7 +189,9 @@ export interface VueConstructor { Methods, Computed, Record, - SetupBindings + SetupBindings, + Mixin, + Extends > /** @@ -172,7 +205,9 @@ export interface VueConstructor { 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 { Methods, Computed, Props, - SetupBindings + SetupBindings, + Mixin, + Extends > ): CombinedVueInstance< V, @@ -188,7 +225,9 @@ export interface VueConstructor { Methods, Computed, Record, - SetupBindings + SetupBindings, + Mixin, + Extends > /** @@ -211,7 +250,9 @@ export interface VueConstructor { 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 { Methods, Computed, PropNames, - SetupBindings + SetupBindings, + Mixin, + Extends > ): ExtendedVue< V, @@ -227,22 +270,43 @@ export interface VueConstructor { Methods, Computed, Record, - SetupBindings + SetupBindings, + Mixin, + Extends > /** * extend with object props */ - extend( + 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 + ): ExtendedVue< + V, + Data, + Methods, + Computed, + Props, + SetupBindings, + Mixin, + Extends + > /** * extend with functional + array props @@ -287,7 +351,9 @@ export interface VueConstructor { 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 { Methods, Computed, PropNames, - SetupBindings + SetupBindings, + Mixin, + Extends > ): ExtendedVue< V, @@ -304,9 +372,19 @@ export interface VueConstructor { Methods, Computed, Record, - SetupBindings + SetupBindings, + Mixin, + Extends > - component( + 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 { Methods, Computed, Props, - SetupBindings + SetupBindings, + Mixin, + Extends > ): ExtendedVue component(