Skip to content

Commit 91c1426

Browse files
committed
feat(types): infer attrs in defineComponent
1 parent c6e5bda commit 91c1426

File tree

6 files changed

+196
-41
lines changed

6 files changed

+196
-41
lines changed

packages/runtime-core/src/apiDefineComponent.ts

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type DefineComponent<
4141
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
4242
E extends EmitsOptions = {},
4343
EE extends string = string,
44+
Attrs = {},
4445
PP = PublicProps,
4546
Props = Readonly<
4647
PropsOrPropOptions extends ComponentPropsOptions
@@ -61,7 +62,9 @@ export type DefineComponent<
6162
E,
6263
PP & Props,
6364
Defaults,
64-
true
65+
true,
66+
{},
67+
Attrs
6568
> &
6669
Props
6770
> &
@@ -86,12 +89,12 @@ export type DefineComponent<
8689

8790
// overload 1: direct setup function
8891
// (uses user defined props interface)
89-
export function defineComponent<Props, RawBindings = object>(
92+
export function defineComponent<Props, RawBindings = object, Attrs = {}>(
9093
setup: (
9194
props: Readonly<Props>,
92-
ctx: SetupContext
95+
ctx: SetupContext<{}, Attrs>
9396
) => RawBindings | RenderFunction
94-
): DefineComponent<Props, RawBindings>
97+
): DefineComponent<Props, RawBindings, {}, {}, {}, {}, {}, {}, string, Attrs>
9598

9699
// overload 2: object format with no props
97100
// (uses user defined props interface)
@@ -107,9 +110,10 @@ export function defineComponent<
107110
E extends EmitsOptions = {},
108111
EE extends string = string,
109112
I extends ComponentInjectOptions = {},
110-
II extends string = string
113+
II extends string = string,
114+
Attrs = {}
111115
>(
112-
options: ComponentOptionsWithoutProps<
116+
comp: ComponentOptionsWithoutProps<
113117
Props,
114118
RawBindings,
115119
D,
@@ -120,9 +124,13 @@ export function defineComponent<
120124
E,
121125
EE,
122126
I,
123-
II
124-
>
125-
): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>
127+
II,
128+
Attrs
129+
>,
130+
options?: {
131+
attrs: Attrs
132+
}
133+
): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE, Attrs>
126134

127135
// overload 3: object format with array props declaration
128136
// props inferred as { [key in PropNames]?: any }
@@ -138,9 +146,10 @@ export function defineComponent<
138146
E extends EmitsOptions = {},
139147
EE extends string = string,
140148
I extends ComponentInjectOptions = {},
141-
II extends string = string
149+
II extends string = string,
150+
Attrs = {}
142151
>(
143-
options: ComponentOptionsWithArrayProps<
152+
comp: ComponentOptionsWithArrayProps<
144153
PropNames,
145154
RawBindings,
146155
D,
@@ -151,8 +160,12 @@ export function defineComponent<
151160
E,
152161
EE,
153162
I,
154-
II
155-
>
163+
II,
164+
Attrs
165+
>,
166+
options?: {
167+
attrs: Attrs
168+
}
156169
): DefineComponent<
157170
Readonly<{ [key in PropNames]?: any }>,
158171
RawBindings,
@@ -162,7 +175,8 @@ export function defineComponent<
162175
Mixin,
163176
Extends,
164177
E,
165-
EE
178+
EE,
179+
Attrs
166180
>
167181

168182
// overload 4: object format with object props declaration
@@ -180,9 +194,10 @@ export function defineComponent<
180194
E extends EmitsOptions = {},
181195
EE extends string = string,
182196
I extends ComponentInjectOptions = {},
183-
II extends string = string
197+
II extends string = string,
198+
Attrs = {}
184199
>(
185-
options: ComponentOptionsWithObjectProps<
200+
comp: ComponentOptionsWithObjectProps<
186201
PropsOptions,
187202
RawBindings,
188203
D,
@@ -193,11 +208,26 @@ export function defineComponent<
193208
E,
194209
EE,
195210
I,
196-
II
197-
>
198-
): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>
211+
II,
212+
Attrs
213+
>,
214+
options?: {
215+
attrs: Attrs
216+
}
217+
): DefineComponent<
218+
PropsOptions,
219+
RawBindings,
220+
D,
221+
C,
222+
M,
223+
Mixin,
224+
Extends,
225+
E,
226+
EE,
227+
Attrs
228+
>
199229

200230
// implementation, close to no-op
201-
export function defineComponent(options: unknown) {
202-
return isFunction(options) ? { setup: options, name: options.name } : options
231+
export function defineComponent(comp: unknown, options?: unknown) {
232+
return isFunction(comp) ? { setup: comp, name: comp.name } : comp
203233
}

packages/runtime-core/src/apiSetupHelpers.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
setCurrentInstance,
66
SetupContext,
77
createSetupContext,
8-
unsetCurrentInstance
8+
unsetCurrentInstance,
9+
Data
910
} from './component'
1011
import { EmitFn, EmitsOptions } from './componentEmits'
1112
import { ComponentObjectPropsOptions, ExtractPropTypes } from './componentProps'
@@ -182,8 +183,8 @@ export function useSlots(): SetupContext['slots'] {
182183
return getContext().slots
183184
}
184185

185-
export function useAttrs(): SetupContext['attrs'] {
186-
return getContext().attrs
186+
export function useAttrs<T extends Data = {}>(): SetupContext['attrs'] {
187+
return getContext().attrs as T
187188
}
188189

189190
function getContext(): SetupContext {

packages/runtime-core/src/component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ export const enum LifecycleHooks {
181181
}
182182

183183
// use `E extends any` to force evaluating type to fix #2362
184-
export type SetupContext<E = EmitsOptions> = E extends any
184+
export type SetupContext<E = EmitsOptions, Attrs = Data> = E extends any
185185
? {
186-
attrs: Data
186+
attrs: Attrs
187187
slots: Slots
188188
emit: EmitFn<E>
189189
expose: (exposed?: Record<string, any>) => void

packages/runtime-core/src/componentOptions.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ export type ComponentOptionsWithoutProps<
229229
EE extends string = string,
230230
I extends ComponentInjectOptions = {},
231231
II extends string = string,
232+
Attrs = {},
232233
PE = Props & EmitsToProps<E>
233234
> = ComponentOptionsBase<
234235
PE,
@@ -258,7 +259,8 @@ export type ComponentOptionsWithoutProps<
258259
PE,
259260
{},
260261
false,
261-
I
262+
I,
263+
Attrs
262264
>
263265
>
264266

@@ -274,6 +276,7 @@ export type ComponentOptionsWithArrayProps<
274276
EE extends string = string,
275277
I extends ComponentInjectOptions = {},
276278
II extends string = string,
279+
Attrs = {},
277280
Props = Readonly<{ [key in PropNames]?: any }> & EmitsToProps<E>
278281
> = ComponentOptionsBase<
279282
Props,
@@ -303,7 +306,8 @@ export type ComponentOptionsWithArrayProps<
303306
Props,
304307
{},
305308
false,
306-
I
309+
I,
310+
Attrs
307311
>
308312
>
309313

@@ -319,6 +323,7 @@ export type ComponentOptionsWithObjectProps<
319323
EE extends string = string,
320324
I extends ComponentInjectOptions = {},
321325
II extends string = string,
326+
Attrs = {},
322327
Props = Readonly<ExtractPropTypes<PropsOptions>> & EmitsToProps<E>,
323328
Defaults = ExtractDefaultPropTypes<PropsOptions>
324329
> = ComponentOptionsBase<
@@ -349,7 +354,8 @@ export type ComponentOptionsWithObjectProps<
349354
Props,
350355
Defaults,
351356
false,
352-
I
357+
I,
358+
Attrs
353359
>
354360
>
355361

packages/runtime-core/src/componentPublicInstance.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
AllowedComponentProps,
23
ComponentInternalInstance,
34
Data,
45
getExposeProxy,
@@ -144,6 +145,7 @@ export type CreateComponentPublicInstance<
144145
Defaults = {},
145146
MakeDefaultsOptional extends boolean = false,
146147
I extends ComponentInjectOptions = {},
148+
Attrs = {},
147149
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>,
148150
PublicP = UnwrapMixinsType<PublicMixin, 'P'> & EnsureNonVoid<P>,
149151
PublicB = UnwrapMixinsType<PublicMixin, 'B'> & EnsureNonVoid<B>,
@@ -165,7 +167,8 @@ export type CreateComponentPublicInstance<
165167
PublicDefaults,
166168
MakeDefaultsOptional,
167169
ComponentOptionsBase<P, B, D, C, M, Mixin, Extends, E, string, Defaults>,
168-
I
170+
I,
171+
Attrs
169172
>
170173

171174
// public properties exposed on the proxy, which is used as the render context
@@ -181,14 +184,17 @@ export type ComponentPublicInstance<
181184
Defaults = {},
182185
MakeDefaultsOptional extends boolean = false,
183186
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>,
184-
I extends ComponentInjectOptions = {}
187+
I extends ComponentInjectOptions = {},
188+
Attrs = {}
185189
> = {
186190
$: ComponentInternalInstance
187191
$data: D
188192
$props: MakeDefaultsOptional extends true
189-
? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults>
190-
: P & PublicProps
191-
$attrs: Data
193+
? Partial<Defaults> &
194+
Omit<P & PublicProps, keyof Defaults> &
195+
Omit<Attrs, keyof (P & PublicProps)>
196+
: P & PublicProps & Omit<Attrs, keyof (P & PublicProps)>
197+
$attrs: Omit<Attrs, keyof (P & PublicProps)> & AllowedComponentProps
192198
$refs: Data
193199
$slots: Slots
194200
$root: ComponentPublicInstance | null

0 commit comments

Comments
 (0)