From 74201dffc7ba4b798bd06614e4a14999b2faca8e Mon Sep 17 00:00:00 2001 From: tycho Date: Sun, 4 Aug 2024 16:03:59 +0800 Subject: [PATCH] feat(types): provide internal options for using refs type in language tools --- packages/dts-test/defineComponent.test-d.tsx | 19 +++++++++++++++++++ .../runtime-core/src/apiDefineComponent.ts | 12 ++++++++++-- .../src/componentPublicInstance.ts | 7 +++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/dts-test/defineComponent.test-d.tsx b/packages/dts-test/defineComponent.test-d.tsx index 79c2e677d2d..d772e7a9905 100644 --- a/packages/dts-test/defineComponent.test-d.tsx +++ b/packages/dts-test/defineComponent.test-d.tsx @@ -1593,6 +1593,7 @@ describe('expose typing', () => { import type { AllowedComponentProps, ComponentCustomProps, + ComponentInstance, ComponentOptionsMixin, DefineComponent, Directive, @@ -1756,6 +1757,24 @@ describe('__typeEmits backdoor, call signature syntax', () => { c.$emit('update', 123) }) +describe('__typeRefs backdoor', () => { + type Refs = { + foo: number + } + + const Child = defineComponent({ + __typeRefs: {} as Refs, + }) + const Parent = defineComponent({ + __typeRefs: {} as { comp1: ComponentInstance }, + }) + const c = new Parent() + const refs = c.$refs + + expectType(refs.comp1.$refs.foo) + expectType>(refs.comp1) +}) + defineComponent({ props: { foo: [String, null], diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 98e9ae7952c..0dde68f888c 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -67,6 +67,7 @@ export type DefineComponent< Exposed extends string = string, Provide extends ComponentProvideOptions = ComponentProvideOptions, MakeDefaultsOptional extends boolean = true, + TypeRefs extends Record = {}, > = ComponentPublicInstanceConstructor< CreateComponentPublicInstanceWithMixins< Props, @@ -84,7 +85,8 @@ export type DefineComponent< S, LC & GlobalComponents, Directives & GlobalDirectives, - Exposed + Exposed, + TypeRefs > > & ComponentOptionsBase< @@ -209,6 +211,7 @@ export function defineComponent< : { [key in RuntimePropsKeys]?: any } : TypeProps, ResolvedProps = Readonly>, + TypeRefs extends Record = {}, >( options: { props?: (RuntimePropsOptions & ThisType) | RuntimePropsKeys[] @@ -220,6 +223,10 @@ export function defineComponent< * @private for language-tools use only */ __typeEmits?: TypeEmits + /** + * @private for language-tools use only + */ + __typeRefs?: TypeRefs } & ComponentOptionsBase< ResolvedProps, SetupBindings, @@ -279,7 +286,8 @@ export function defineComponent< Provide, // MakeDefaultsOptional - if TypeProps is provided, set to false to use // user props types verbatim - unknown extends TypeProps ? true : false + unknown extends TypeProps ? true : false, + TypeRefs > // implementation, close to no-op diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 41fce67d0c5..9ab6df52d6d 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -232,6 +232,7 @@ export type CreateComponentPublicInstanceWithMixins< LC extends Record = {}, Directives extends Record = {}, Exposed extends string = string, + TypeRefs extends Data = {}, Provide extends ComponentProvideOptions = ComponentProvideOptions, // mixin inference PublicMixin = IntersectionMixin & IntersectionMixin, @@ -275,7 +276,8 @@ export type CreateComponentPublicInstanceWithMixins< >, I, S, - Exposed + Exposed, + TypeRefs > export type ExposedKeys< @@ -299,6 +301,7 @@ export type ComponentPublicInstance< I extends ComponentInjectOptions = {}, S extends SlotsType = {}, Exposed extends string = '', + TypeRefs extends Data = {}, > = { $: ComponentInternalInstance $data: D @@ -306,7 +309,7 @@ export type ComponentPublicInstance< ? Partial & Omit & PublicProps, keyof Defaults> : Prettify

& PublicProps $attrs: Data - $refs: Data + $refs: Data & TypeRefs $slots: UnwrapSlotsType $root: ComponentPublicInstance | null $parent: ComponentPublicInstance | null