From e2cac0776920657a6171a58c56cdb5913842078d Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 9 Mar 2021 11:26:12 +0000 Subject: [PATCH 01/31] types(defineComponent): support for expose component types --- .../runtime-core/src/apiDefineComponent.ts | 75 ++++++++++++++++--- packages/runtime-core/src/componentOptions.ts | 54 +++++++++++-- .../src/componentPublicInstance.ts | 25 ++++++- test-dts/defineComponent.test-d.tsx | 17 +++++ 4 files changed, 151 insertions(+), 20 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 333d18a30f3..01aab7bdc1f 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -11,7 +11,8 @@ import { import { SetupContext, AllowedComponentProps, - ComponentCustomProps + ComponentCustomProps, + Component } from './component' import { ExtractPropTypes, @@ -25,6 +26,7 @@ import { CreateComponentPublicInstance, ComponentPublicInstanceConstructor } from './componentPublicInstance' +import { Directive } from './directives' export type PublicProps = VNodeProps & AllowedComponentProps & @@ -40,6 +42,9 @@ export type DefineComponent< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record, EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string, PP = PublicProps, Props = Readonly>, Defaults = ExtractDefaultPropTypes @@ -69,6 +74,9 @@ export type DefineComponent< Extends, E, EE, + LC, + Directives, + Exposed, Defaults > & PP @@ -99,7 +107,10 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, - EE extends string = string + EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string >( options: ComponentOptionsWithoutProps< Props, @@ -110,9 +121,25 @@ export function defineComponent< Mixin, Extends, E, - EE + EE, + LC, + Directives, + Exposed > -): DefineComponent +): DefineComponent< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + LC, + Directives, + Exposed +> // overload 3: object format with array props declaration // props inferred as { [key in PropNames]?: any } @@ -126,7 +153,10 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record, - EE extends string = string + EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string >( options: ComponentOptionsWithArrayProps< PropNames, @@ -137,7 +167,10 @@ export function defineComponent< Mixin, Extends, E, - EE + EE, + LC, + Directives, + Exposed > ): DefineComponent< Readonly<{ [key in PropNames]?: any }>, @@ -148,7 +181,10 @@ export function defineComponent< Mixin, Extends, E, - EE + EE, + LC, + Directives, + Exposed > // overload 4: object format with object props declaration @@ -164,7 +200,10 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record, - EE extends string = string + EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string >( options: ComponentOptionsWithObjectProps< PropsOptions, @@ -175,9 +214,25 @@ export function defineComponent< Mixin, Extends, E, - EE + EE, + LC, + Directives, + Exposed > -): DefineComponent +): DefineComponent< + PropsOptions, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + LC, + Directives, + Exposed +> // implementation, close to no-op export function defineComponent(options: unknown) { diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 70948d41cf9..00ef198137c 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -104,6 +104,9 @@ export interface ComponentOptionsBase< Extends extends ComponentOptionsMixin, E extends EmitsOptions, EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string, Defaults = {} > extends LegacyOptions, @@ -124,12 +127,12 @@ export interface ComponentOptionsBase< // Luckily `render()` doesn't need any arguments nor does it care about return // type. render?: Function - components?: Record - directives?: Record + components?: LC + directives?: Directives inheritAttrs?: boolean emits?: (E | EE[]) & ThisType // TODO infer public instance type based on exposed keys - expose?: string[] + expose?: Exposed[] serverPrefetch?(): Promise // Internal ------------------------------------------------------------------ @@ -194,7 +197,10 @@ export type ComponentOptionsWithoutProps< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, - EE extends string = string + EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string > = ComponentOptionsBase< Props, RawBindings, @@ -205,6 +211,9 @@ export type ComponentOptionsWithoutProps< Extends, E, EE, + LC, + Directives, + Exposed, {} > & { props?: undefined @@ -222,6 +231,9 @@ export type ComponentOptionsWithArrayProps< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string, Props = Readonly<{ [key in PropNames]?: any }> > = ComponentOptionsBase< Props, @@ -233,6 +245,9 @@ export type ComponentOptionsWithArrayProps< Extends, E, EE, + LC, + Directives, + Exposed, {} > & { props: PropNames[] @@ -245,7 +260,13 @@ export type ComponentOptionsWithArrayProps< M, Mixin, Extends, - E + E, + Props, + {}, + false, + LC, + Directives, + Exposed > > @@ -259,6 +280,9 @@ export type ComponentOptionsWithObjectProps< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, EE extends string = string, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string, Props = Readonly>, Defaults = ExtractDefaultPropTypes > = ComponentOptionsBase< @@ -271,6 +295,9 @@ export type ComponentOptionsWithObjectProps< Extends, E, EE, + LC, + Directives, + Exposed, Defaults > & { props: PropsOptions & ThisType @@ -286,7 +313,10 @@ export type ComponentOptionsWithObjectProps< E, Props, Defaults, - false + false, + LC, + Directives, + Exposed > > @@ -298,7 +328,10 @@ export type ComponentOptions< M extends MethodOptions = any, Mixin extends ComponentOptionsMixin = any, Extends extends ComponentOptionsMixin = any, - E extends EmitsOptions = any + E extends EmitsOptions = any, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string > = ComponentOptionsBase & ThisType< CreateComponentPublicInstance< @@ -310,7 +343,12 @@ export type ComponentOptions< Mixin, Extends, E, - Readonly + Readonly, + {}, + false, + LC, + Directives, + Exposed > > diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index bbdb0336092..9c63ab8d9a2 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -1,4 +1,5 @@ import { + Component, ComponentInternalInstance, Data, isStatefulComponent @@ -39,6 +40,7 @@ import { markAttrsAccessed } from './componentRenderUtils' import { currentRenderingInstance } from './componentRenderContext' import { warn } from './warning' import { UnionToIntersection } from './helpers/typeUtils' +import { Directive } from './directives' /** * Custom properties added to component instances in any way and can be accessed through `this` @@ -136,6 +138,9 @@ export type CreateComponentPublicInstance< PublicProps = P, Defaults = {}, MakeDefaultsOptional extends boolean = false, + LC extends Record = {}, + Directives extends Record = {}, + Exposed extends string = string, PublicMixin = IntersectionMixin & IntersectionMixin, PublicP = UnwrapMixinsType & EnsureNonVoid

, PublicB = UnwrapMixinsType & EnsureNonVoid, @@ -156,7 +161,22 @@ export type CreateComponentPublicInstance< PublicProps, PublicDefaults, MakeDefaultsOptional, - ComponentOptionsBase + ComponentOptionsBase< + P, + B, + D, + C, + M, + Mixin, + Extends, + E, + string, + LC, + Directives, + Exposed, + Defaults + >, + Exposed > // public properties exposed on the proxy, which is used as the render context @@ -171,7 +191,8 @@ export type ComponentPublicInstance< PublicProps = P, Defaults = {}, MakeDefaultsOptional extends boolean = false, - Options = ComponentOptionsBase + Options = ComponentOptionsBase, + Exposed extends string = string > = { $: ComponentInternalInstance $data: D diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 949654b1b9e..fa32b4dc5c4 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -963,6 +963,23 @@ describe('async setup', () => { vm.a = 2 }) +// #3367 expose components types +describe('expose component types', () => { + const child = defineComponent({ + props: { + a: String + } + }) + + const parent = defineComponent({ + components: { + child + } + }) + + expect(parent.components!.child) +}) + // check if defineComponent can be exported export default { // function components From 3ccdc0bdd3f7825a70c8675d17402b74c1ac95f5 Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 9 Mar 2021 11:48:34 +0000 Subject: [PATCH 02/31] chore: add directive typing test --- packages/runtime-core/src/component.ts | 5 +++++ packages/runtime-core/src/componentOptions.ts | 17 +++++++++++++++- test-dts/defineComponent.test-d.tsx | 20 ++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index bfb7736b410..a8b34e1da00 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -62,6 +62,11 @@ export type Data = Record */ export interface ComponentCustomProps {} +/** + * For globally defined Directives + */ +export interface ComponentCustomDirectives extends Record {} + /** * Default allowed non-declared props on component in TSX */ diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 00ef198137c..071df938a77 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -218,7 +218,22 @@ export type ComponentOptionsWithoutProps< > & { props?: undefined } & ThisType< - CreateComponentPublicInstance<{}, RawBindings, D, C, M, Mixin, Extends, E> + CreateComponentPublicInstance< + {}, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + Props, + {}, + false, + LC, + Directives, + Exposed + > > export type ComponentOptionsWithArrayProps< diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index fa32b4dc5c4..13b98edf74b 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -11,7 +11,8 @@ import { ComponentPublicInstance, ComponentOptions, SetupContext, - h + h, + Directive } from './index' describe('with object props', () => { @@ -980,6 +981,23 @@ describe('expose component types', () => { expect(parent.components!.child) }) +describe('directive typing', () => { + const customDirective: Directive = { + created(el) {} + } + + const comp = defineComponent({ + props: { + a: String + }, + directives: { + customDirective + } + }) + + expect(comp.directives!.customDirective) +}) + // check if defineComponent can be exported export default { // function components From e140b07eb17e58e50f73af23ac272835896190ed Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 9 Mar 2021 12:11:54 +0000 Subject: [PATCH 03/31] chore: exposed type suppor --- .../runtime-core/src/apiDefineComponent.ts | 7 +++++- packages/runtime-core/src/componentOptions.ts | 3 +-- .../src/componentPublicInstance.ts | 22 +++++++++++------ test-dts/defineComponent.test-d.tsx | 24 +++++++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 01aab7bdc1f..92f1a750a23 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -32,6 +32,8 @@ export type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps +// TODO add Com + export type DefineComponent< PropsOrPropOptions = {}, RawBindings = {}, @@ -60,7 +62,10 @@ export type DefineComponent< E, PP & Props, Defaults, - true + true, + LC, + Directives, + Exposed > & Props > & diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 071df938a77..f93cf9daa4c 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -330,8 +330,7 @@ export type ComponentOptionsWithObjectProps< Defaults, false, LC, - Directives, - Exposed + Directives > > diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 9c63ab8d9a2..e77832a7bb1 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -179,6 +179,11 @@ export type CreateComponentPublicInstance< Exposed > +export type ExposedKeys< + T, + Exposed extends string & keyof T +> = '' extends Exposed ? T : Pick + // public properties exposed on the proxy, which is used as the render context // in templates (as `this` in the render option) export type ComponentPublicInstance< @@ -192,7 +197,7 @@ export type ComponentPublicInstance< Defaults = {}, MakeDefaultsOptional extends boolean = false, Options = ComponentOptionsBase, - Exposed extends string = string + Exposed extends string = '' > = { $: ComponentInternalInstance $data: D @@ -214,12 +219,15 @@ export type ComponentPublicInstance< cb: Function, options?: WatchOptions ): WatchStopHandle -} & P & - ShallowUnwrapRef & - D & - ExtractComputedReturns & - M & - ComponentCustomProperties +} & ExposedKeys< + P & + ShallowUnwrapRef & + D & + ExtractComputedReturns & + M & + ComponentCustomProperties, + Exposed +> type PublicPropertiesMap = Record any> diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 13b98edf74b..876d9822228 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -998,6 +998,30 @@ describe('directive typing', () => { expect(comp.directives!.customDirective) }) +describe('expose typing', () => { + const Comp = defineComponent({ + expose: ['a', 'b'], + props: { + some: String + }, + data() { + return { a: 1, b: '2', c: 1 } + } + }) + + expect>(Comp.expose!) + + const vm = new Comp() + // internal should still be exposed + vm.$props + + expectType(vm.a) + expectType(vm.b) + + // @ts-expect-error shouldn't be exposed + vm.c +}) + // check if defineComponent can be exported export default { // function components From 5f49e9c11eb8565d5ca99f13d00f3f81f0801d0b Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 9 Mar 2021 12:24:33 +0000 Subject: [PATCH 04/31] chore: add global directive type --- packages/runtime-core/src/apiDefineComponent.ts | 9 ++++----- packages/runtime-core/src/index.ts | 3 ++- test-dts/componentTypeExtensions.test-d.tsx | 7 ++++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 92f1a750a23..36a296eea04 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -12,7 +12,8 @@ import { SetupContext, AllowedComponentProps, ComponentCustomProps, - Component + Component, + ComponentCustomDirectives } from './component' import { ExtractPropTypes, @@ -32,8 +33,6 @@ export type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps -// TODO add Com - export type DefineComponent< PropsOrPropOptions = {}, RawBindings = {}, @@ -64,7 +63,7 @@ export type DefineComponent< Defaults, true, LC, - Directives, + Directives & ComponentCustomDirectives, Exposed > & Props @@ -80,7 +79,7 @@ export type DefineComponent< E, EE, LC, - Directives, + Directives & ComponentCustomDirectives, Exposed, Defaults > & diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 98ba289f565..4940edf8d3a 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -166,7 +166,8 @@ export { ComponentInternalInstance, SetupContext, ComponentCustomProps, - AllowedComponentProps + AllowedComponentProps, + ComponentCustomDirectives } from './component' export { DefineComponent } from './apiDefineComponent' export { diff --git a/test-dts/componentTypeExtensions.test-d.tsx b/test-dts/componentTypeExtensions.test-d.tsx index 32a72f844e6..3dbce81a506 100644 --- a/test-dts/componentTypeExtensions.test-d.tsx +++ b/test-dts/componentTypeExtensions.test-d.tsx @@ -1,10 +1,14 @@ -import { defineComponent, expectError, expectType } from './index' +import { defineComponent, Directive, expectError, expectType } from './index' declare module '@vue/runtime-core' { interface ComponentCustomOptions { test?(n: number): void } + interface ComponentCustomDirectives { + test: Directive + } + interface ComponentCustomProperties { state: 'stopped' | 'running' } @@ -41,6 +45,7 @@ export const Custom = defineComponent({ } }) +expectType(Custom.directives!.test) expectType() expectType() expectType() From fbb62bc0c9ee2aab4d10ec1314e15abb84a1056d Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 9 Mar 2021 12:41:47 +0000 Subject: [PATCH 05/31] chore: fix tests --- packages/runtime-core/src/componentOptions.ts | 18 +++++++++++++++--- .../src/componentPublicInstance.ts | 3 +++ test-dts/defineComponent.test-d.tsx | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index f93cf9daa4c..79b0ec2e075 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -346,7 +346,20 @@ export type ComponentOptions< LC extends Record = {}, Directives extends Record = {}, Exposed extends string = string -> = ComponentOptionsBase & +> = ComponentOptionsBase< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + string, + LC, + Directives, + Exposed +> & ThisType< CreateComponentPublicInstance< {}, @@ -361,8 +374,7 @@ export type ComponentOptions< {}, false, LC, - Directives, - Exposed + Directives > > diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index e77832a7bb1..1fb18e0670b 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -83,6 +83,9 @@ type MixinToOptionTypes = T extends ComponentOptionsBase< infer Extends, any, any, + any, + any, + any, infer Defaults > ? OptionTypesType

& diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 876d9822228..4e810e47a64 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -718,6 +718,8 @@ describe('extends with mixins', () => { // Test TSX expectType() + expectType() + // mP1, mP2, p1, and p2 have default value. these are not required expectType() From b10bc7750eb60107a74eebee3dea14b6eb1e9dba Mon Sep 17 00:00:00 2001 From: pikax Date: Wed, 10 Mar 2021 08:11:17 +0000 Subject: [PATCH 06/31] chore: clean dup code --- test-dts/defineComponent.test-d.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 4e810e47a64..876d9822228 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -718,8 +718,6 @@ describe('extends with mixins', () => { // Test TSX expectType() - expectType() - // mP1, mP2, p1, and p2 have default value. these are not required expectType() From d0b13fa681a3266c724582b297786a928659713a Mon Sep 17 00:00:00 2001 From: pikax Date: Thu, 11 Mar 2021 16:30:04 +0000 Subject: [PATCH 07/31] chore: add GlobalComponents and GlobalDirectives --- .../runtime-core/src/apiDefineComponent.ts | 11 ++++--- packages/runtime-core/src/component.ts | 31 ++++++++++++++++++- packages/runtime-core/src/componentOptions.ts | 1 - packages/runtime-core/src/index.ts | 3 +- test-dts/componentTypeExtensions.test-d.tsx | 15 +++++++-- test-dts/defineComponent.test-d.tsx | 6 ++-- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 36a296eea04..449140ed326 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -13,7 +13,8 @@ import { AllowedComponentProps, ComponentCustomProps, Component, - ComponentCustomDirectives + GlobalDirectives, + GlobalComponents } from './component' import { ExtractPropTypes, @@ -62,8 +63,8 @@ export type DefineComponent< PP & Props, Defaults, true, - LC, - Directives & ComponentCustomDirectives, + LC & GlobalComponents, + Directives & GlobalDirectives, Exposed > & Props @@ -78,8 +79,8 @@ export type DefineComponent< Extends, E, EE, - LC, - Directives & ComponentCustomDirectives, + LC & GlobalComponents, + Directives & GlobalDirectives, Exposed, Defaults > & diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index a8b34e1da00..52e90d263c6 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -64,8 +64,37 @@ export interface ComponentCustomProps {} /** * For globally defined Directives + * Here is an example of adding a directive `VTooltip` as global directive: + * + * @example + * ```ts + * import VTooltip from 'v-tooltip' + * + * declare module '@vue/runtime-core' { + * interface GlobalDirectives { + * VTooltip + * } + * } + * ``` */ -export interface ComponentCustomDirectives extends Record {} +export interface GlobalDirectives extends Record {} + +/** + * For globally defined Components + * Here is an example of adding a component `RouterView` as global component: + * + * @example + * ```ts + * import { RouterView } from 'vue-router' + * + * declare module '@vue/runtime-core' { + * interface GlobalComponents { + * RouterView + * } + * } + * ``` + */ +export interface GlobalComponents extends Record {} /** * Default allowed non-declared props on component in TSX diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 79b0ec2e075..5764d998bb2 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -131,7 +131,6 @@ export interface ComponentOptionsBase< directives?: Directives inheritAttrs?: boolean emits?: (E | EE[]) & ThisType - // TODO infer public instance type based on exposed keys expose?: Exposed[] serverPrefetch?(): Promise diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 4940edf8d3a..ff38b75f039 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -167,7 +167,8 @@ export { SetupContext, ComponentCustomProps, AllowedComponentProps, - ComponentCustomDirectives + GlobalComponents, + GlobalDirectives } from './component' export { DefineComponent } from './apiDefineComponent' export { diff --git a/test-dts/componentTypeExtensions.test-d.tsx b/test-dts/componentTypeExtensions.test-d.tsx index 3dbce81a506..46da0724f9c 100644 --- a/test-dts/componentTypeExtensions.test-d.tsx +++ b/test-dts/componentTypeExtensions.test-d.tsx @@ -1,14 +1,24 @@ -import { defineComponent, Directive, expectError, expectType } from './index' +import { + defineComponent, + DefineComponent, + Directive, + expectError, + expectType +} from './index' declare module '@vue/runtime-core' { interface ComponentCustomOptions { test?(n: number): void } - interface ComponentCustomDirectives { + interface GlobalDirectives { test: Directive } + interface GlobalComponents { + RouterView: DefineComponent<{}> + } + interface ComponentCustomProperties { state: 'stopped' | 'running' } @@ -46,6 +56,7 @@ export const Custom = defineComponent({ }) expectType(Custom.directives!.test) +expectType>(Custom.components!.RouterView) expectType() expectType() expectType() diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 876d9822228..4fcf771c7a3 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -978,7 +978,7 @@ describe('expose component types', () => { } }) - expect(parent.components!.child) + expectType(parent.components!.child) }) describe('directive typing', () => { @@ -995,7 +995,7 @@ describe('directive typing', () => { } }) - expect(comp.directives!.customDirective) + expectType(comp.directives!.customDirective) }) describe('expose typing', () => { @@ -1009,7 +1009,7 @@ describe('expose typing', () => { } }) - expect>(Comp.expose!) + expectType>(Comp.expose!) const vm = new Comp() // internal should still be exposed From 057bad9f64a8b93167c2d3b1e005010b9808aadc Mon Sep 17 00:00:00 2001 From: pikax Date: Sat, 13 Mar 2021 08:41:57 +0000 Subject: [PATCH 08/31] chore: add Suspense, KeepAlive, Teleport to GlobalComponents --- packages/runtime-core/src/index.ts | 19 +++++++++++++++++-- .../runtime-core/types/globalComponents.d.ts | 10 ++++++++++ test-dts/defineComponent.test-d.tsx | 9 +++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 packages/runtime-core/types/globalComponents.d.ts diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index ff38b75f039..c7a5d7ac776 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -118,6 +118,21 @@ declare module '@vue/reactivity' { } } +// Augment GlobalComponents +// Note: if updating this, also update `types/globalComponents.d.ts`. +import { TeleportProps } from './components/Teleport' +import { SuspenseProps } from './components/Suspense' +import { KeepAliveProps } from './components/KeepAlive' +import { DefineComponent } from './apiDefineComponent' + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + Teleport: DefineComponent + Suspense: DefineComponent + KeepAlive: DefineComponent + } +} + export { ReactiveEffect, ReactiveEffectOptions, @@ -167,8 +182,8 @@ export { SetupContext, ComponentCustomProps, AllowedComponentProps, - GlobalComponents, - GlobalDirectives + GlobalDirectives, + GlobalComponents } from './component' export { DefineComponent } from './apiDefineComponent' export { diff --git a/packages/runtime-core/types/globalComponents.d.ts b/packages/runtime-core/types/globalComponents.d.ts new file mode 100644 index 00000000000..d3cd069e6c4 --- /dev/null +++ b/packages/runtime-core/types/globalComponents.d.ts @@ -0,0 +1,10 @@ +// Note: this file is auto concatenated to the end of the bundled d.ts during +// build. + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + Teleport: DefineComponent + Suspense: DefineComponent + KeepAlive: DefineComponent + } +} diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 4fcf771c7a3..46676c98c31 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -12,7 +12,8 @@ import { ComponentOptions, SetupContext, h, - Directive + Directive, + KeepAliveProps } from './index' describe('with object props', () => { @@ -979,6 +980,10 @@ describe('expose component types', () => { }) expectType(parent.components!.child) + + // global components + expectType(new parent.components!.KeepAlive().$props) + expectType(new child.components!.KeepAlive().$props) }) describe('directive typing', () => { @@ -1009,7 +1014,7 @@ describe('expose typing', () => { } }) - expectType>(Comp.expose!) + expect>(Comp.expose!) const vm = new Comp() // internal should still be exposed From 9970b4510b46fd3fdc9e5a229439e0776fb39517 Mon Sep 17 00:00:00 2001 From: pikax Date: Sat, 13 Mar 2021 09:12:30 +0000 Subject: [PATCH 09/31] chore: add Transition and TransitionGroup to globalComponents --- packages/runtime-dom/src/index.ts | 13 ++++++++++++- packages/runtime-dom/types/globalComponents.d.ts | 9 +++++++++ test-dts/defineComponent.test-d.tsx | 7 ++++++- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 packages/runtime-dom/types/globalComponents.d.ts diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 773470621fe..bd47e96d800 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -8,12 +8,15 @@ import { HydrationRenderer, App, RootHydrateFunction, - isRuntimeOnly + isRuntimeOnly, + DefineComponent } from '@vue/runtime-core' import { nodeOps } from './nodeOps' import { patchProp, forcePatchProp } from './patchProp' // Importing from the compiler, will be tree-shaken in prod import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared' +import { TransitionProps } from './components/Transition' +import { TransitionGroupProps } from './components/TransitionGroup' declare module '@vue/reactivity' { export interface RefUnwrapBailTypes { @@ -22,6 +25,14 @@ declare module '@vue/reactivity' { } } +declare module '@vue/runtime-core' { + interface GlobalComponents { + // Note: if updating this, also update `types/globalComponents.d.ts`. + Transition: DefineComponent + TransitionGroup: DefineComponent + } +} + const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps) // lazy create the renderer - this makes core renderer logic tree-shakable diff --git a/packages/runtime-dom/types/globalComponents.d.ts b/packages/runtime-dom/types/globalComponents.d.ts new file mode 100644 index 00000000000..025e76bb30a --- /dev/null +++ b/packages/runtime-dom/types/globalComponents.d.ts @@ -0,0 +1,9 @@ +// Note: this file is auto concatenated to the end of the bundled d.ts during +// build. + +declare module '@vue/runtime-core' { + interface GlobalComponents { + Transition: DefineComponent + TransitionGroup: DefineComponent + } +} diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 46676c98c31..1abd3f955ea 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -13,7 +13,8 @@ import { SetupContext, h, Directive, - KeepAliveProps + KeepAliveProps, + TransitionProps } from './index' describe('with object props', () => { @@ -984,6 +985,10 @@ describe('expose component types', () => { // global components expectType(new parent.components!.KeepAlive().$props) expectType(new child.components!.KeepAlive().$props) + + // runtime-dom components + expectType(new parent.components!.Transition().$props) + expectType(new parent.components!.Transition().$props) }) describe('directive typing', () => { From 2498929394e8d8d9c08ce01c30c4861046a457e9 Mon Sep 17 00:00:00 2001 From: pikax Date: Sat, 13 Mar 2021 09:18:25 +0000 Subject: [PATCH 10/31] chore: add BaseTransition ass globalComponent --- packages/runtime-core/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index c7a5d7ac776..a1b5edf93aa 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -123,6 +123,7 @@ declare module '@vue/reactivity' { import { TeleportProps } from './components/Teleport' import { SuspenseProps } from './components/Suspense' import { KeepAliveProps } from './components/KeepAlive' +import { BaseTransitionProps } from './components/BaseTransition' import { DefineComponent } from './apiDefineComponent' declare module '@vue/runtime-core' { @@ -130,6 +131,7 @@ declare module '@vue/runtime-core' { Teleport: DefineComponent Suspense: DefineComponent KeepAlive: DefineComponent + BaseTransition: DefineComponent } } From b792c6c9f8ab42708d90b861f38034c4d5445062 Mon Sep 17 00:00:00 2001 From: pikax Date: Sat, 13 Mar 2021 09:24:19 +0000 Subject: [PATCH 11/31] chore: add VShow as a globalDirective --- packages/runtime-dom/src/index.ts | 5 +++++ packages/runtime-dom/types/globalComponents.d.ts | 5 ++--- packages/runtime-dom/types/globalDirectives.d.ts | 9 +++++++++ test-dts/defineComponent.test-d.tsx | 6 +++++- 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 packages/runtime-dom/types/globalDirectives.d.ts diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index bd47e96d800..3e2e736342c 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -17,6 +17,7 @@ import { patchProp, forcePatchProp } from './patchProp' import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared' import { TransitionProps } from './components/Transition' import { TransitionGroupProps } from './components/TransitionGroup' +import { vShow } from './directives/vShow' declare module '@vue/reactivity' { export interface RefUnwrapBailTypes { @@ -31,6 +32,10 @@ declare module '@vue/runtime-core' { Transition: DefineComponent TransitionGroup: DefineComponent } + + interface GlobalDirectives { + vShow: typeof vShow + } } const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps) diff --git a/packages/runtime-dom/types/globalComponents.d.ts b/packages/runtime-dom/types/globalComponents.d.ts index 025e76bb30a..041d85e90fb 100644 --- a/packages/runtime-dom/types/globalComponents.d.ts +++ b/packages/runtime-dom/types/globalComponents.d.ts @@ -2,8 +2,7 @@ // build. declare module '@vue/runtime-core' { - interface GlobalComponents { - Transition: DefineComponent - TransitionGroup: DefineComponent + interface GlobalDirectives { + vShow: typeof vShow } } diff --git a/packages/runtime-dom/types/globalDirectives.d.ts b/packages/runtime-dom/types/globalDirectives.d.ts new file mode 100644 index 00000000000..025e76bb30a --- /dev/null +++ b/packages/runtime-dom/types/globalDirectives.d.ts @@ -0,0 +1,9 @@ +// Note: this file is auto concatenated to the end of the bundled d.ts during +// build. + +declare module '@vue/runtime-core' { + interface GlobalComponents { + Transition: DefineComponent + TransitionGroup: DefineComponent + } +} diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 1abd3f955ea..9ee7cd6fe8a 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -14,7 +14,8 @@ import { h, Directive, KeepAliveProps, - TransitionProps + TransitionProps, + vShow } from './index' describe('with object props', () => { @@ -1006,6 +1007,9 @@ describe('directive typing', () => { }) expectType(comp.directives!.customDirective) + + // global directive + expectType(comp.directives!.vShow) }) describe('expose typing', () => { From 980dbf3c26d602766ee2aceceaf0d8a4fb5796ee Mon Sep 17 00:00:00 2001 From: pikax Date: Sat, 13 Mar 2021 14:28:02 +0000 Subject: [PATCH 12/31] chore: add BaseTransition --- packages/runtime-core/types/globalComponents.d.ts | 1 + packages/runtime-dom/types/globalDirectives.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/runtime-core/types/globalComponents.d.ts b/packages/runtime-core/types/globalComponents.d.ts index d3cd069e6c4..a4abd6d1fff 100644 --- a/packages/runtime-core/types/globalComponents.d.ts +++ b/packages/runtime-core/types/globalComponents.d.ts @@ -6,5 +6,6 @@ declare module '@vue/runtime-core' { Teleport: DefineComponent Suspense: DefineComponent KeepAlive: DefineComponent + BaseTransition: DefineComponent } } diff --git a/packages/runtime-dom/types/globalDirectives.d.ts b/packages/runtime-dom/types/globalDirectives.d.ts index 025e76bb30a..28d1bfc87c4 100644 --- a/packages/runtime-dom/types/globalDirectives.d.ts +++ b/packages/runtime-dom/types/globalDirectives.d.ts @@ -1,6 +1,7 @@ // Note: this file is auto concatenated to the end of the bundled d.ts during // build. +import { DefineComponent } from '@vue/runtime-core' declare module '@vue/runtime-core' { interface GlobalComponents { Transition: DefineComponent From 200838d6edfb0f59f08e2bf69a463e433a05648b Mon Sep 17 00:00:00 2001 From: pikax Date: Sun, 14 Mar 2021 09:23:23 +0000 Subject: [PATCH 13/31] chore: correct interface with file name --- packages/runtime-dom/types/globalComponents.d.ts | 6 ++++-- packages/runtime-dom/types/globalDirectives.d.ts | 6 ++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/runtime-dom/types/globalComponents.d.ts b/packages/runtime-dom/types/globalComponents.d.ts index 041d85e90fb..28d1bfc87c4 100644 --- a/packages/runtime-dom/types/globalComponents.d.ts +++ b/packages/runtime-dom/types/globalComponents.d.ts @@ -1,8 +1,10 @@ // Note: this file is auto concatenated to the end of the bundled d.ts during // build. +import { DefineComponent } from '@vue/runtime-core' declare module '@vue/runtime-core' { - interface GlobalDirectives { - vShow: typeof vShow + interface GlobalComponents { + Transition: DefineComponent + TransitionGroup: DefineComponent } } diff --git a/packages/runtime-dom/types/globalDirectives.d.ts b/packages/runtime-dom/types/globalDirectives.d.ts index 28d1bfc87c4..041d85e90fb 100644 --- a/packages/runtime-dom/types/globalDirectives.d.ts +++ b/packages/runtime-dom/types/globalDirectives.d.ts @@ -1,10 +1,8 @@ // Note: this file is auto concatenated to the end of the bundled d.ts during // build. -import { DefineComponent } from '@vue/runtime-core' declare module '@vue/runtime-core' { - interface GlobalComponents { - Transition: DefineComponent - TransitionGroup: DefineComponent + interface GlobalDirectives { + vShow: typeof vShow } } From 08c121785acc4a388f9854c384f580f1c416c315 Mon Sep 17 00:00:00 2001 From: pikax Date: Tue, 30 Mar 2021 16:28:20 +0100 Subject: [PATCH 14/31] chore: wrap component to get the type --- packages/server-renderer/__tests__/render.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts index 67bc23450b8..f01aef06793 100644 --- a/packages/server-renderer/__tests__/render.spec.ts +++ b/packages/server-renderer/__tests__/render.spec.ts @@ -834,11 +834,11 @@ function testRender(type: string, render: typeof renderToString) { await render( createApp({ components: { - A: { + A: defineComponent({ ssrRender(_ctx, _push) { _push(`

A
`) } - }, + }), B: { render: () => h('div', 'B') } From ca63ffa174ce88865d1ae2b5368e718c49185d51 Mon Sep 17 00:00:00 2001 From: pikax Date: Thu, 15 Apr 2021 19:02:45 +0100 Subject: [PATCH 15/31] chore: typed directives + VModel directive --- packages/runtime-core/src/directives.ts | 43 +++++++++++++------ packages/runtime-dom/src/directives/vModel.ts | 12 ++++-- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/packages/runtime-core/src/directives.ts b/packages/runtime-core/src/directives.ts index 20f25d03ee9..5442dc890fe 100644 --- a/packages/runtime-core/src/directives.ts +++ b/packages/runtime-core/src/directives.ts @@ -19,18 +19,28 @@ import { currentRenderingInstance } from './componentRenderContext' import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' import { ComponentPublicInstance } from './componentPublicInstance' -export interface DirectiveBinding { +export interface DirectiveBinding< + V = any, + Arg extends string = string, + Modifiers extends string = string +> { instance: ComponentPublicInstance | null value: V oldValue: V | null - arg?: string - modifiers: DirectiveModifiers + arg?: Arg + modifiers: DirectiveModifiers dir: ObjectDirective } -export type DirectiveHook | null, V = any> = ( +export type DirectiveHook< + T = any, + Prev = VNode | null, + V = any, + Arg extends string = string, + Modifiers extends string = string +> = ( el: T, - binding: DirectiveBinding, + binding: DirectiveBinding, vnode: VNode, prevVNode: Prev ) => void @@ -40,14 +50,19 @@ export type SSRDirectiveHook = ( vnode: VNode ) => Data | undefined -export interface ObjectDirective { - created?: DirectiveHook - beforeMount?: DirectiveHook - mounted?: DirectiveHook - beforeUpdate?: DirectiveHook, V> - updated?: DirectiveHook, V> - beforeUnmount?: DirectiveHook - unmounted?: DirectiveHook +export interface ObjectDirective< + T = any, + V = any, + Arg extends string = string, + Modifiers extends string = string +> { + created?: DirectiveHook + beforeMount?: DirectiveHook + mounted?: DirectiveHook + beforeUpdate?: DirectiveHook, V, Arg, Modifiers> + updated?: DirectiveHook, V, Arg, Modifiers> + beforeUnmount?: DirectiveHook + unmounted?: DirectiveHook getSSRProps?: SSRDirectiveHook } @@ -57,7 +72,7 @@ export type Directive = | ObjectDirective | FunctionDirective -export type DirectiveModifiers = Record +export type DirectiveModifiers = Record const isBuiltInDirective = /*#__PURE__*/ makeMap( 'bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text' diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index a90c4466a17..1894d8e65a7 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -40,12 +40,18 @@ function trigger(el: HTMLElement, type: string) { el.dispatchEvent(e) } -type ModelDirective = ObjectDirective +type ModelDirective = ObjectDirective< + T & { _assign: AssignerFn }, + any, + string, + Modifiers +> // We are exporting the v-model runtime directly as vnode hooks so that it can // be tree-shaken in case v-model is never used. export const vModelText: ModelDirective< - HTMLInputElement | HTMLTextAreaElement + HTMLInputElement | HTMLTextAreaElement, + 'trim' | 'number' | 'lazy' > = { created(el, { modifiers: { lazy, trim, number } }, vnode) { el._assign = getModelAssigner(vnode) @@ -170,7 +176,7 @@ export const vModelRadio: ModelDirective = { } } -export const vModelSelect: ModelDirective = { +export const vModelSelect: ModelDirective = { created(el, { value, modifiers: { number } }, vnode) { const isSetModel = isSet(value) addEventListener(el, 'change', () => { From 16352ca65cdad5787c145113d328123fa72379da Mon Sep 17 00:00:00 2001 From: pikax Date: Sun, 18 Apr 2021 09:52:45 +0100 Subject: [PATCH 16/31] chore: move arg after modifiers and add tests --- packages/runtime-core/src/directives.ts | 80 ++++++++++++------- packages/runtime-dom/src/directives/vModel.ts | 1 - test-dts/directives.test-d.ts | 47 +++++++++++ 3 files changed, 98 insertions(+), 30 deletions(-) create mode 100644 test-dts/directives.test-d.ts diff --git a/packages/runtime-core/src/directives.ts b/packages/runtime-core/src/directives.ts index 5442dc890fe..772316872b8 100644 --- a/packages/runtime-core/src/directives.ts +++ b/packages/runtime-core/src/directives.ts @@ -20,28 +20,28 @@ import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' import { ComponentPublicInstance } from './componentPublicInstance' export interface DirectiveBinding< - V = any, - Arg extends string = string, - Modifiers extends string = string + Value = any, + Modifiers extends string = string, + Arg extends string = string > { instance: ComponentPublicInstance | null - value: V - oldValue: V | null + value: Value + oldValue: Value | null arg?: Arg modifiers: DirectiveModifiers - dir: ObjectDirective + dir: ObjectDirective } export type DirectiveHook< - T = any, - Prev = VNode | null, - V = any, - Arg extends string = string, - Modifiers extends string = string + HostElement = any, + Prev = VNode | null, + Value = any, + Modifiers extends string = string, + Arg extends string = string > = ( - el: T, - binding: DirectiveBinding, - vnode: VNode, + el: HostElement, + binding: DirectiveBinding, + vnode: VNode, prevVNode: Prev ) => void @@ -51,26 +51,48 @@ export type SSRDirectiveHook = ( ) => Data | undefined export interface ObjectDirective< - T = any, - V = any, - Arg extends string = string, - Modifiers extends string = string + HostElement = any, + Value = any, + Modifiers extends string = string, + Arg extends string = string > { - created?: DirectiveHook - beforeMount?: DirectiveHook - mounted?: DirectiveHook - beforeUpdate?: DirectiveHook, V, Arg, Modifiers> - updated?: DirectiveHook, V, Arg, Modifiers> - beforeUnmount?: DirectiveHook - unmounted?: DirectiveHook + created?: DirectiveHook + beforeMount?: DirectiveHook + mounted?: DirectiveHook + beforeUpdate?: DirectiveHook< + HostElement, + VNode, + Value, + Arg, + Modifiers + > + updated?: DirectiveHook< + HostElement, + VNode, + Value, + Arg, + Modifiers + > + beforeUnmount?: DirectiveHook + unmounted?: DirectiveHook getSSRProps?: SSRDirectiveHook } -export type FunctionDirective = DirectiveHook +export type FunctionDirective< + HostElement = any, + V = any, + Modifiers extends string = string, + Arg extends string = string +> = DirectiveHook -export type Directive = - | ObjectDirective - | FunctionDirective +export type Directive< + HostElement = any, + Value = any, + Modifiers extends string = string, + Arg extends string = string +> = + | ObjectDirective + | FunctionDirective export type DirectiveModifiers = Record diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 1894d8e65a7..14f3e9ea473 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -43,7 +43,6 @@ function trigger(el: HTMLElement, type: string) { type ModelDirective = ObjectDirective< T & { _assign: AssignerFn }, any, - string, Modifiers > diff --git a/test-dts/directives.test-d.ts b/test-dts/directives.test-d.ts new file mode 100644 index 00000000000..d6ec3d15854 --- /dev/null +++ b/test-dts/directives.test-d.ts @@ -0,0 +1,47 @@ +import { Directive, expectError, expectType } from './index' + +type ExtractBinding = T extends ( + el: any, + binding: infer B, + vnode: any, + prev: any +) => any + ? B + : never + +declare function testDirective< + Value, + Modifiers extends string = string, + Arg extends string = string +>(): ExtractBinding> + +expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> +}>(testDirective()) + +expectError<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error +}>(testDirective()) + +expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error +}>(testDirective()) + +expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error +}>(testDirective()) From 7754d7eed73f8993c7df6f27d26052e3df4fd773 Mon Sep 17 00:00:00 2001 From: pikax Date: Sun, 18 Apr 2021 10:10:12 +0100 Subject: [PATCH 17/31] chore: improve tests --- packages/runtime-core/src/directives.ts | 26 +++++----- test-dts/directives.test-d.ts | 69 ++++++++++++++----------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/packages/runtime-core/src/directives.ts b/packages/runtime-core/src/directives.ts index 772316872b8..4bc63050c7d 100644 --- a/packages/runtime-core/src/directives.ts +++ b/packages/runtime-core/src/directives.ts @@ -40,7 +40,7 @@ export type DirectiveHook< Arg extends string = string > = ( el: HostElement, - binding: DirectiveBinding, + binding: DirectiveBinding, vnode: VNode, prevVNode: Prev ) => void @@ -56,25 +56,25 @@ export interface ObjectDirective< Modifiers extends string = string, Arg extends string = string > { - created?: DirectiveHook - beforeMount?: DirectiveHook - mounted?: DirectiveHook + created?: DirectiveHook + beforeMount?: DirectiveHook + mounted?: DirectiveHook beforeUpdate?: DirectiveHook< HostElement, VNode, Value, - Arg, - Modifiers + Modifiers, + Arg > updated?: DirectiveHook< HostElement, VNode, Value, - Arg, - Modifiers + Modifiers, + Arg > - beforeUnmount?: DirectiveHook - unmounted?: DirectiveHook + beforeUnmount?: DirectiveHook + unmounted?: DirectiveHook getSSRProps?: SSRDirectiveHook } @@ -83,7 +83,7 @@ export type FunctionDirective< V = any, Modifiers extends string = string, Arg extends string = string -> = DirectiveHook +> = DirectiveHook export type Directive< HostElement = any, @@ -91,8 +91,8 @@ export type Directive< Modifiers extends string = string, Arg extends string = string > = - | ObjectDirective - | FunctionDirective + | ObjectDirective + | FunctionDirective export type DirectiveModifiers = Record diff --git a/test-dts/directives.test-d.ts b/test-dts/directives.test-d.ts index d6ec3d15854..700c9727292 100644 --- a/test-dts/directives.test-d.ts +++ b/test-dts/directives.test-d.ts @@ -1,4 +1,5 @@ -import { Directive, expectError, expectType } from './index' +import { ObjectDirective } from '@vue/runtime-core' +import { Directive, expectError, expectType, vModelText } from './index' type ExtractBinding = T extends ( el: any, @@ -13,35 +14,45 @@ declare function testDirective< Value, Modifiers extends string = string, Arg extends string = string ->(): ExtractBinding> +>(): ExtractBinding> -expectType<{ - value: number - oldValue: number | null - arg?: 'Arg' - modifiers: Record<'a' | 'b', boolean> -}>(testDirective()) - -expectError<{ - value: number - oldValue: number | null - arg?: 'Arg' - modifiers: Record<'a' | 'b', boolean> +describe('vmodel', () => { + expectType>( + vModelText + ) // @ts-expect-error -}>(testDirective()) + expectType>(vModelText) +}) -expectType<{ - value: number - oldValue: number | null - arg?: 'Arg' - modifiers: Record<'a' | 'b', boolean> - // @ts-expect-error -}>(testDirective()) +describe('custom', () => { + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + }>(testDirective()) -expectType<{ - value: number - oldValue: number | null - arg?: 'Arg' - modifiers: Record<'a' | 'b', boolean> - // @ts-expect-error -}>(testDirective()) + expectError<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) + + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) + + expectType<{ + value: number + oldValue: number | null + arg?: 'Arg' + modifiers: Record<'a' | 'b', boolean> + // @ts-expect-error + }>(testDirective()) +}) From 6558afdbd43e5069246305da373f506e03498081 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Fri, 23 Apr 2021 11:16:40 +0100 Subject: [PATCH 18/31] chore: add vOn directive as global --- packages/runtime-dom/src/directives/vOn.ts | 52 +++++++++++++--------- packages/runtime-dom/src/index.ts | 2 + 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/runtime-dom/src/directives/vOn.ts b/packages/runtime-dom/src/directives/vOn.ts index ce4a4d0c293..891ef1a6bd6 100644 --- a/packages/runtime-dom/src/directives/vOn.ts +++ b/packages/runtime-dom/src/directives/vOn.ts @@ -1,31 +1,39 @@ import { hyphenate } from '@vue/shared' - -const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'] +import { Directive } from 'test-dts' type KeyedEvent = KeyboardEvent | MouseEvent | TouchEvent -const modifierGuards: Record< - string, - (e: Event, modifiers: string[]) => void | boolean -> = { - stop: e => e.stopPropagation(), - prevent: e => e.preventDefault(), - self: e => e.target !== e.currentTarget, - ctrl: e => !(e as KeyedEvent).ctrlKey, - shift: e => !(e as KeyedEvent).shiftKey, - alt: e => !(e as KeyedEvent).altKey, - meta: e => !(e as KeyedEvent).metaKey, - left: e => 'button' in e && (e as MouseEvent).button !== 0, - middle: e => 'button' in e && (e as MouseEvent).button !== 1, - right: e => 'button' in e && (e as MouseEvent).button !== 2, - exact: (e, modifiers) => +type SystemModifiers = 'ctrl' | 'shift' | 'alt' | 'meta' +type CompatModifiers = keyof typeof keyNames + +export type VOnModifiers = SystemModifiers | ModifierGuards | CompatModifiers + +const systemModifiers: Array = ['ctrl', 'shift', 'alt', 'meta'] + +const modifierGuards = { + stop: (e: Event) => e.stopPropagation(), + prevent: (e: Event) => e.preventDefault(), + self: (e: Event) => e.target !== e.currentTarget, + ctrl: (e: Event) => !(e as KeyedEvent).ctrlKey, + shift: (e: Event) => !(e as KeyedEvent).shiftKey, + alt: (e: Event) => !(e as KeyedEvent).altKey, + meta: (e: Event) => !(e as KeyedEvent).metaKey, + left: (e: Event) => 'button' in e && (e as MouseEvent).button !== 0, + middle: (e: Event) => 'button' in e && (e as MouseEvent).button !== 1, + right: (e: Event) => 'button' in e && (e as MouseEvent).button !== 2, + exact: (e: Event, modifiers: string[]) => systemModifiers.some(m => (e as any)[`${m}Key`] && !modifiers.includes(m)) } +type ModifierGuards = keyof typeof modifierGuards + /** * @private */ -export const withModifiers = (fn: Function, modifiers: string[]) => { +export const withModifiers = ( + fn: Function, + modifiers: Array +) => { return (event: Event, ...args: unknown[]) => { for (let i = 0; i < modifiers.length; i++) { const guard = modifierGuards[modifiers[i]] @@ -37,7 +45,7 @@ export const withModifiers = (fn: Function, modifiers: string[]) => { // Kept for 2.x compat. // Note: IE11 compat for `spacebar` and `del` is removed for now. -const keyNames: Record = { +const keyNames = { esc: 'escape', space: ' ', up: 'arrow-up', @@ -56,10 +64,14 @@ export const withKeys = (fn: Function, modifiers: string[]) => { const eventKey = hyphenate(event.key) if ( // None of the provided key modifiers match the current event key - !modifiers.some(k => k === eventKey || keyNames[k] === eventKey) + !modifiers.some( + k => k === eventKey || keyNames[k as CompatModifiers] === eventKey + ) ) { return } return fn(event) } } + +export type VOnDirective = Directive diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 3e2e736342c..2115d3fadb9 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -18,6 +18,7 @@ import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared' import { TransitionProps } from './components/Transition' import { TransitionGroupProps } from './components/TransitionGroup' import { vShow } from './directives/vShow' +import { VOnDirective } from './directives/vOn' declare module '@vue/reactivity' { export interface RefUnwrapBailTypes { @@ -35,6 +36,7 @@ declare module '@vue/runtime-core' { interface GlobalDirectives { vShow: typeof vShow + vOn: VOnDirective } } From 99741b8610d680a86ff055d277a6a905b4a7e2e8 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sun, 25 Apr 2021 14:16:18 +0100 Subject: [PATCH 19/31] chore: vmodel WIP --- packages/runtime-dom/src/directives/vModel.ts | 7 +++++++ packages/runtime-dom/src/index.ts | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 14f3e9ea473..72507b46458 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -325,3 +325,10 @@ if (__NODE_JS__) { } } } + +export type VModelDirective = + | typeof vModelText + | typeof vModelCheckbox + | typeof vModelSelect + | typeof vModelRadio + | typeof vModelDynamic diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 2115d3fadb9..e2223a9364d 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -9,7 +9,10 @@ import { App, RootHydrateFunction, isRuntimeOnly, - DefineComponent + DefineComponent, + Directive, + Directive, + Directive } from '@vue/runtime-core' import { nodeOps } from './nodeOps' import { patchProp, forcePatchProp } from './patchProp' @@ -19,6 +22,7 @@ import { TransitionProps } from './components/Transition' import { TransitionGroupProps } from './components/TransitionGroup' import { vShow } from './directives/vShow' import { VOnDirective } from './directives/vOn' +import { VModelDirective } from './directives/vModel' declare module '@vue/reactivity' { export interface RefUnwrapBailTypes { @@ -35,8 +39,13 @@ declare module '@vue/runtime-core' { } interface GlobalDirectives { + // Note: if updating this, also update `types/globalDirectives.d.ts`. vShow: typeof vShow vOn: VOnDirective + vBind: VModelDirective + vIf: Directive + VOnce: Directive + VSlot: Directive } } From 5573d90a057f03ba264df89b3a22e1258a05f4f9 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sun, 15 Aug 2021 09:20:48 +0100 Subject: [PATCH 20/31] chore: remove bad import and fix compat render type --- packages/runtime-core/src/compat/global.ts | 9 ++++++--- packages/vue-compat/__tests__/instance.spec.ts | 11 +++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/runtime-core/src/compat/global.ts b/packages/runtime-core/src/compat/global.ts index 7f66e5dad59..15a4d9f7e0f 100644 --- a/packages/runtime-core/src/compat/global.ts +++ b/packages/runtime-core/src/compat/global.ts @@ -57,7 +57,7 @@ import { isCompatEnabled, softAssertCompatEnabled } from './compatConfig' -import { LegacyPublicInstance } from './instance' +import { LegacyPublicInstance, LegacyPublicProperties } from './instance' /** * @deprecated the default `Vue` export has been removed in Vue 3. The type for @@ -78,7 +78,7 @@ export type CompatVue = Pick & { nextTick: typeof nextTick use(plugin: Plugin, ...options: any[]): CompatVue - mixin(mixin: ComponentOptions): CompatVue + mixin(mixin: LegacyComponentOptions): CompatVue component(name: string): Component | undefined component(name: string, component: Component): CompatVue @@ -90,7 +90,7 @@ export type CompatVue = Pick & { /** * @deprecated */ - extend: (options?: ComponentOptions) => CompatVue + extend: (options?: LegacyComponentOptions) => CompatVue /** * @deprecated Vue 3 no longer needs set() for adding new properties. */ @@ -125,6 +125,9 @@ export type CompatVue = Pick & { super: CompatVue } +type LegacyComponentOptions = ComponentOptions & + ThisType + export let isCopyingConfig = false // exported only for test diff --git a/packages/vue-compat/__tests__/instance.spec.ts b/packages/vue-compat/__tests__/instance.spec.ts index 8b11b3d6c75..08029fb8b43 100644 --- a/packages/vue-compat/__tests__/instance.spec.ts +++ b/packages/vue-compat/__tests__/instance.spec.ts @@ -7,7 +7,6 @@ import { toggleDeprecationWarning } from '../../runtime-core/src/compat/compatConfig' import { LegacyPublicInstance } from '../../runtime-core/src/compat/instance' -import { defineComponent } from 'test-dts' beforeEach(() => { toggleDeprecationWarning(true) @@ -240,7 +239,8 @@ test('INSTANCE_LISTENERS', () => { components: { child: { template: `
`, - mounted() { + mounted(this: LegacyPublicInstance) { + // @ts-expect-error $listeners type: Record listeners = this.$listeners } } @@ -264,7 +264,7 @@ describe('INSTANCE_SCOPED_SLOTS', () => { components: { child: { compatConfig: { RENDER_FUNCTION: false }, - render() { + render(this: LegacyPublicInstance) { slots = this.$scopedSlots } } @@ -291,11 +291,14 @@ describe('INSTANCE_SCOPED_SLOTS', () => { components: { child: { compatConfig: { RENDER_FUNCTION: false }, - render() { + render(this: LegacyPublicInstance) { normalSlots = this.$slots scopedSlots = this.$scopedSlots } } + }, + render() { + this.$ } }).$mount() From a3408d7e0ab9da06ac6eec514321f956a4c2863d Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sun, 15 Aug 2021 09:25:44 +0100 Subject: [PATCH 21/31] chore: remove type --- packages/runtime-core/src/compat/global.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/compat/global.ts b/packages/runtime-core/src/compat/global.ts index 15a4d9f7e0f..7f66e5dad59 100644 --- a/packages/runtime-core/src/compat/global.ts +++ b/packages/runtime-core/src/compat/global.ts @@ -57,7 +57,7 @@ import { isCompatEnabled, softAssertCompatEnabled } from './compatConfig' -import { LegacyPublicInstance, LegacyPublicProperties } from './instance' +import { LegacyPublicInstance } from './instance' /** * @deprecated the default `Vue` export has been removed in Vue 3. The type for @@ -78,7 +78,7 @@ export type CompatVue = Pick & { nextTick: typeof nextTick use(plugin: Plugin, ...options: any[]): CompatVue - mixin(mixin: LegacyComponentOptions): CompatVue + mixin(mixin: ComponentOptions): CompatVue component(name: string): Component | undefined component(name: string, component: Component): CompatVue @@ -90,7 +90,7 @@ export type CompatVue = Pick & { /** * @deprecated */ - extend: (options?: LegacyComponentOptions) => CompatVue + extend: (options?: ComponentOptions) => CompatVue /** * @deprecated Vue 3 no longer needs set() for adding new properties. */ @@ -125,9 +125,6 @@ export type CompatVue = Pick & { super: CompatVue } -type LegacyComponentOptions = ComponentOptions & - ThisType - export let isCopyingConfig = false // exported only for test From 37593c941ac00804b0cb44527ee5c637604299bf Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 5 Feb 2022 09:30:17 +0000 Subject: [PATCH 22/31] minor: fix ssrCompiler test --- .../server-renderer/__tests__/ssrCompilerOptions.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts b/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts index 2ff588a5c77..ef8f1a98818 100644 --- a/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts +++ b/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts @@ -2,7 +2,7 @@ * @jest-environment node */ -import { createApp } from 'vue' +import { createApp, defineComponent } from 'vue' import { renderToString } from '../src/renderToString' describe('ssr: compiler options', () => { @@ -125,7 +125,7 @@ describe('ssr: compiler options', () => { template, // No compilerOptions on the root components: { - MyChild: { + MyChild: defineComponent({ template, compilerOptions: { isCustomElement: tag => tag.startsWith('x-') @@ -138,7 +138,7 @@ describe('ssr: compiler options', () => { } } } - } + }) } }) expect(await renderToString(app)).toBe( From b26801183165f8ec1b6456c0a3b26a8f1083ffb9 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 5 Feb 2022 10:14:45 +0000 Subject: [PATCH 23/31] minor: remove breaking code -.-' --- packages/vue-compat/__tests__/instance.spec.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/vue-compat/__tests__/instance.spec.ts b/packages/vue-compat/__tests__/instance.spec.ts index 63f34e11a4e..16cfa326aee 100644 --- a/packages/vue-compat/__tests__/instance.spec.ts +++ b/packages/vue-compat/__tests__/instance.spec.ts @@ -296,9 +296,6 @@ describe('INSTANCE_SCOPED_SLOTS', () => { scopedSlots = this.$scopedSlots } } - }, - render() { - this.$ } }).$mount() From 1269ab1dc56788eb2d63bfad61f7ff6f58944032 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 5 Feb 2022 10:49:59 +0000 Subject: [PATCH 24/31] minor: fix tests and remove unnecessary defineComponent --- packages/runtime-core/src/componentOptions.ts | 10 ++++++++-- .../__tests__/ssrCompilerOptions.spec.ts | 6 +++--- packages/vue-compat/__tests__/instance.spec.ts | 5 ++--- test-dts/defineComponent.test-d.tsx | 16 +++++++++++++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 600560d67ad..016279ea04a 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -143,8 +143,14 @@ export interface ComponentOptionsBase< // Luckily `render()` doesn't need any arguments nor does it care about return // type. render?: Function - components?: LC - directives?: Directives + + // NOTE: extending both LC and Record allows objects to be forced + // to be of type Component, while still inferring LC generic + components?: LC & Record + // NOTE: extending both Directives and Record allows objects to be forced + // to be of type Directive, while still inferring Directives generic + directives?: Directives & Record + inheritAttrs?: boolean emits?: (E | EE[]) & ThisType expose?: Exposed[] diff --git a/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts b/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts index ef8f1a98818..2ff588a5c77 100644 --- a/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts +++ b/packages/server-renderer/__tests__/ssrCompilerOptions.spec.ts @@ -2,7 +2,7 @@ * @jest-environment node */ -import { createApp, defineComponent } from 'vue' +import { createApp } from 'vue' import { renderToString } from '../src/renderToString' describe('ssr: compiler options', () => { @@ -125,7 +125,7 @@ describe('ssr: compiler options', () => { template, // No compilerOptions on the root components: { - MyChild: defineComponent({ + MyChild: { template, compilerOptions: { isCustomElement: tag => tag.startsWith('x-') @@ -138,7 +138,7 @@ describe('ssr: compiler options', () => { } } } - }) + } } }) expect(await renderToString(app)).toBe( diff --git a/packages/vue-compat/__tests__/instance.spec.ts b/packages/vue-compat/__tests__/instance.spec.ts index 16cfa326aee..fc81885626c 100644 --- a/packages/vue-compat/__tests__/instance.spec.ts +++ b/packages/vue-compat/__tests__/instance.spec.ts @@ -239,8 +239,7 @@ test('INSTANCE_LISTENERS', () => { components: { child: { template: `
`, - mounted(this: LegacyPublicInstance) { - // @ts-expect-error $listeners type: Record + mounted() { listeners = this.$listeners } } @@ -264,7 +263,7 @@ describe('INSTANCE_SCOPED_SLOTS', () => { components: { child: { compatConfig: { RENDER_FUNCTION: false }, - render(this: LegacyPublicInstance) { + render() { slots = this.$scopedSlots } } diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index ff1363e72b0..8895df4b2c2 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -1138,11 +1138,15 @@ describe('expose component types', () => { const parent = defineComponent({ components: { - child + child, + child2: { + template: `
` + } } }) expectType(parent.components!.child) + expectType(parent.components!.child2) // global components expectType(new parent.components!.KeepAlive().$props) @@ -1155,7 +1159,7 @@ describe('expose component types', () => { describe('directive typing', () => { const customDirective: Directive = { - created(el) {} + created(_) {} } const comp = defineComponent({ @@ -1163,11 +1167,17 @@ describe('directive typing', () => { a: String }, directives: { - customDirective + customDirective, + localDirective: { + created(_, { arg }) { + expectType(arg) + } + } } }) expectType(comp.directives!.customDirective) + expectType(comp.directives!.localDirective) // global directive expectType(comp.directives!.vShow) From 50b17d4656ad32e0d228daa7db8b351b313e8d21 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 5 Feb 2022 10:58:24 +0000 Subject: [PATCH 25/31] chore: remove added defineComponent --- packages/server-renderer/__tests__/render.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server-renderer/__tests__/render.spec.ts b/packages/server-renderer/__tests__/render.spec.ts index d7739111d36..96e16750917 100644 --- a/packages/server-renderer/__tests__/render.spec.ts +++ b/packages/server-renderer/__tests__/render.spec.ts @@ -856,11 +856,11 @@ function testRender(type: string, render: typeof renderToString) { await render( createApp({ components: { - A: defineComponent({ + A: { ssrRender(_ctx, _push) { _push(`
A
`) } - }), + }, B: { render: () => h('div', 'B') } From fa99b4203f0e9eeb7ea6cbf6302311a50a213f1d Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Wed, 11 May 2022 17:18:52 +0100 Subject: [PATCH 26/31] fix bad merge --- .../runtime-core/src/apiDefineComponent.ts | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 7d3126a3a78..ea4d3c997d0 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -181,21 +181,22 @@ export function defineComponent< Provide extends ComponentProvideOptions = ComponentProvideOptions, Options extends {} = {} >( - options: ComponentOptionsWithArrayProps< - PropNames, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE, - LC, - Directives, - Exposed, - Provide - > + options: Options & + ComponentOptionsWithArrayProps< + PropNames, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + LC, + Directives, + Exposed, + Provide + > ): DefineComponent< Readonly<{ [key in PropNames]?: any }>, RawBindings, @@ -233,21 +234,22 @@ export function defineComponent< Provide extends ComponentProvideOptions = ComponentProvideOptions, Options extends {} = {} >( - options: ComponentOptionsWithObjectProps< - PropsOptions, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE, - LC, - Directives, - Exposed, - Provide - > + options: Options & + ComponentOptionsWithObjectProps< + PropsOptions, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + LC, + Directives, + Exposed, + Provide + > ): DefineComponent< PropsOptions, RawBindings, From 6f0042edb7ebaa473e2be77774db55753a5cf568 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 09:43:43 +0000 Subject: [PATCH 27/31] [autofix.ci] apply automated fixes --- .../componentTypeExtensions.test-d.tsx | 2 +- packages/dts-test/defineComponent.test-d.tsx | 12 ++++++++--- .../src/componentPublicInstance.ts | 20 ++++++++++--------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/dts-test/componentTypeExtensions.test-d.tsx b/packages/dts-test/componentTypeExtensions.test-d.tsx index d13ceb5cc2c..7bb6f59566e 100644 --- a/packages/dts-test/componentTypeExtensions.test-d.tsx +++ b/packages/dts-test/componentTypeExtensions.test-d.tsx @@ -5,7 +5,7 @@ declare module 'vue' { interface ComponentCustomOptions { test?(n: number): void } - + interface GlobalDirectives { test: Directive } diff --git a/packages/dts-test/defineComponent.test-d.tsx b/packages/dts-test/defineComponent.test-d.tsx index 00f96755bb6..abb1d592e89 100644 --- a/packages/dts-test/defineComponent.test-d.tsx +++ b/packages/dts-test/defineComponent.test-d.tsx @@ -1497,12 +1497,18 @@ describe('expose component types', () => { expectType(parent.components!.child2) // global components - expectType>(new parent.components!.KeepAlive().$props) + expectType>( + new parent.components!.KeepAlive().$props + ) expectType>(new child.components!.KeepAlive().$props) // runtime-dom components - expectType>(new parent.components!.Transition().$props) - expectType>(new child.components!.Transition().$props) + expectType>( + new parent.components!.Transition().$props + ) + expectType>( + new child.components!.Transition().$props + ) }) describe('directive typing', () => { diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index fcfb61fdb98..833869e1142 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -82,7 +82,7 @@ type IsDefaultMixinComponent = T extends ComponentOptionsMixin : false : false - // TODO-CR check this +// TODO-CR check this type MixinToOptionTypes = T extends ComponentOptionsBase< infer P, infer B, @@ -247,14 +247,16 @@ export type ComponentPublicInstance< : (...args: any) => any, options?: WatchOptions ): WatchStopHandle -} & ExposedKeys

& - UnwrapNestedRefs & - ExtractComputedReturns & - M & - ComponentCustomProperties & - InjectToObject, - Exposed> +} & ExposedKeys< + P & + ShallowUnwrapRef & + UnwrapNestedRefs & + ExtractComputedReturns & + M & + ComponentCustomProperties & + InjectToObject, + Exposed +> export type PublicPropertiesMap = Record< string, From f9754a67e5ea8e8e492ce47bb203fd1fe598db31 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 21 Oct 2023 10:45:46 +0100 Subject: [PATCH 28/31] format and remove comment --- packages/runtime-core/src/componentPublicInstance.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 833869e1142..3accd2dfe43 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -82,7 +82,6 @@ type IsDefaultMixinComponent = T extends ComponentOptionsMixin : false : false -// TODO-CR check this type MixinToOptionTypes = T extends ComponentOptionsBase< infer P, infer B, @@ -96,6 +95,10 @@ type MixinToOptionTypes = T extends ComponentOptionsBase< infer Defaults, any, any, + any, + any, + any, + any, any > ? OptionTypesType

& From 9b983982e20335aaf01a950fd932f03144553134 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Sat, 21 Oct 2023 11:19:59 +0100 Subject: [PATCH 29/31] chore: remove RawOptions from defineComponent --- .../runtime-core/src/apiDefineComponent.ts | 93 +++++++++---------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 0e154d5fdf9..b0d3bfd1a7f 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -63,8 +63,7 @@ export type DefineComponent< LC extends Record = {}, Directives extends Record = {}, Exposed extends string = string, - Provide extends ComponentProvideOptions = ComponentProvideOptions, - Options extends {} = {} + Provide extends ComponentProvideOptions = ComponentProvideOptions > = ComponentPublicInstanceConstructor< CreateComponentPublicInstance< Props, @@ -166,28 +165,26 @@ export function defineComponent< LC extends Record = {}, Directives extends Record = {}, Exposed extends string = string, - Provide extends ComponentProvideOptions = ComponentProvideOptions, - Options extends {} = {} + Provide extends ComponentProvideOptions = ComponentProvideOptions >( - options: Options & - ComponentOptionsWithoutProps< - Props, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE, - I, - II, - S, - LC, - Directives, - Exposed, - Provide - > + options: ComponentOptionsWithoutProps< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + I, + II, + S, + LC, + Directives, + Exposed, + Provide + > ): DefineComponent< Props, RawBindings, @@ -205,8 +202,7 @@ export function defineComponent< LC, Directives, Exposed, - Provide, - Options + Provide > // overload 3: object format with array props declaration @@ -229,28 +225,26 @@ export function defineComponent< Directives extends Record = {}, Exposed extends string = string, Provide extends ComponentProvideOptions = ComponentProvideOptions, - Options extends {} = {}, Props = Readonly<{ [key in PropNames]?: any }> >( - options: Options & - ComponentOptionsWithArrayProps< - PropNames, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE, - I, - II, - S, - LC, - Directives, - Exposed, - Provide - > + options: ComponentOptionsWithArrayProps< + PropNames, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + I, + II, + S, + LC, + Directives, + Exposed, + Provide + > ): DefineComponent< Props, RawBindings, @@ -268,8 +262,7 @@ export function defineComponent< LC, Directives, Exposed, - Provide, - Options + Provide > // overload 4: object format with object props declaration @@ -292,8 +285,7 @@ export function defineComponent< LC extends Record = {}, Directives extends Record = {}, Exposed extends string = string, - Provide extends ComponentProvideOptions = ComponentProvideOptions, - Options extends {} = {} + Provide extends ComponentProvideOptions = ComponentProvideOptions >( options: ComponentOptionsWithObjectProps< PropsOptions, @@ -330,8 +322,7 @@ export function defineComponent< LC, Directives, Exposed, - Provide, - Options + Provide > // implementation, close to no-op From 34a53915db55a4cc60f906f3d6ad35ac02cd74a8 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 11:56:49 +0000 Subject: [PATCH 30/31] [autofix.ci] apply automated fixes --- packages/runtime-core/src/apiDefineComponent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 661e3ac6958..d998943cbcf 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -82,7 +82,7 @@ export type DefineComponent< LC & GlobalComponents, Directives & GlobalDirectives, Exposed - > + > > & ComponentOptionsBase< Props, From 6eda2d5c6da81921933b15e513154825397b6d69 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Wed, 22 Nov 2023 13:33:49 +0000 Subject: [PATCH 31/31] chore: fix vuetify usage --- packages/dts-test/appUse.test-d.ts | 14 +++++++++++++- packages/dts-test/directives.test-d.ts | 2 +- packages/runtime-core/src/apiCreateApp.ts | 3 ++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/dts-test/appUse.test-d.ts b/packages/dts-test/appUse.test-d.ts index c1bebcd53e3..ebfc986a757 100644 --- a/packages/dts-test/appUse.test-d.ts +++ b/packages/dts-test/appUse.test-d.ts @@ -1,4 +1,4 @@ -import { createApp, App, Plugin } from 'vue' +import { createApp, App, Plugin, defineComponent } from 'vue' const app = createApp({}) @@ -93,3 +93,15 @@ const PluginTyped: Plugin = (app, options) => {} // @ts-expect-error: needs options app.use(PluginTyped) app.use(PluginTyped, { option2: 2, option3: true }) + +// vuetify usage +const key: string = '' +const aliases: Record = {} +app.component( + key, + defineComponent({ + ...aliases[key], + name: key, + aliasName: aliases[key].name + }) +) diff --git a/packages/dts-test/directives.test-d.ts b/packages/dts-test/directives.test-d.ts index 6c94ecc64f3..2d0ed24f8c0 100644 --- a/packages/dts-test/directives.test-d.ts +++ b/packages/dts-test/directives.test-d.ts @@ -21,7 +21,7 @@ describe('vmodel', () => { vModelText ) // @ts-expect-error - expectType>(vModelText) + expectType>(vModelText) }) describe('custom', () => { diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 8e4ab1f3aa0..8e58e69378e 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -27,6 +27,7 @@ import { version } from '.' import { installAppCompatProperties } from './compat/global' import { NormalizedPropsOptions } from './componentProps' import { ObjectEmitsOptions } from './componentEmits' +import { DefineComponent } from './apiDefineComponent' export interface App { version: string @@ -40,7 +41,7 @@ export interface App { mixin(mixin: ComponentOptions): this component(name: string): Component | undefined - component(name: string, component: Component): this + component(name: string, component: Component | DefineComponent): this directive(name: string): Directive | undefined directive(name: string, directive: Directive): this mount(