Skip to content

Commit b8a0891

Browse files
committed
feat: add ExtractPropsAndEvents util
1 parent 9c2916a commit b8a0891

File tree

6 files changed

+49
-28
lines changed

6 files changed

+49
-28
lines changed

packages/dts-test/defineComponent.test-d.tsx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
Slots,
1515
VNode,
1616
ImgHTMLAttributes,
17-
StyleValue
17+
StyleValue,
18+
ExtractPropsAndEvents
1819
} from 'vue'
1920
import { describe, expectType, IsUnion, test } from './utils'
2021

@@ -1326,8 +1327,7 @@ describe('define attrs', () => {
13261327
// @ts-expect-error
13271328
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
13281329
})
1329-
1330-
test('wrap elements, such as img element (Keep the volar plugin open)', () => {
1330+
test('wrap elements', () => {
13311331
const MyImg = defineComponent({
13321332
props: {
13331333
foo: String
@@ -1344,13 +1344,14 @@ describe('define attrs', () => {
13441344
expectType<JSX.Element>(<MyImg class={'str'} style={'str'} src={'str'} />)
13451345
})
13461346

1347-
test('secondary packaging of components', () => {
1348-
const childProps = {
1349-
foo: String
1350-
}
1351-
type ChildProps = ExtractPropTypes<typeof childProps>
1347+
test('wrap components', () => {
13521348
const Child = defineComponent({
1353-
props: childProps,
1349+
props: {
1350+
foo: String
1351+
},
1352+
emits: {
1353+
baz: (val: number) => true
1354+
},
13541355
render() {
13551356
return <div>{this.foo}</div>
13561357
}
@@ -1359,13 +1360,25 @@ describe('define attrs', () => {
13591360
props: {
13601361
bar: Number
13611362
},
1362-
attrs: Object as AttrsType<ChildProps>,
1363+
attrs: Object as AttrsType<ExtractPropsAndEvents<typeof Child>>,
1364+
created() {
1365+
expectType<unknown>(this.$attrs.class)
1366+
expectType<unknown>(this.$attrs.style)
1367+
},
13631368
render() {
13641369
return <Child {...this.$attrs} />
13651370
}
13661371
})
13671372
expectType<JSX.Element>(
1368-
<Comp class={'str'} style={'str'} bar={1} foo={'str'} />
1373+
<Comp
1374+
class={'str'}
1375+
style={'str'}
1376+
bar={1}
1377+
foo={'str'}
1378+
onBaz={val => {
1379+
expectType<number>(val)
1380+
}}
1381+
/>
13691382
)
13701383
})
13711384
})

packages/runtime-core/src/apiDefineComponent.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
SetupContext,
1717
AllowedComponentProps,
1818
ComponentCustomProps,
19-
noAttrsDefine
19+
HasDefinedAttrs
2020
} from './component'
2121
import {
2222
ExtractPropTypes,
@@ -109,9 +109,9 @@ export function defineComponent<
109109
EE extends string = string,
110110
S extends SlotsType = {},
111111
Attrs extends AttrsType = Record<string, unknown>,
112-
PropsAttrs = noAttrsDefine<Attrs> extends true
113-
? {}
114-
: UnwrapAttrsType<NonNullable<Attrs>>
112+
PropsAttrs = HasDefinedAttrs<Attrs> extends true
113+
? UnwrapAttrsType<NonNullable<Attrs>>
114+
: {}
115115
>(
116116
setup: (
117117
props: Props,

packages/runtime-core/src/component.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ import { SchedulerJob } from './scheduler'
8484
import { LifecycleHooks } from './enums'
8585

8686
export type Data = Record<string, unknown>
87-
// Whether the attrs option is not defined
88-
export type noAttrsDefine<T> = Equal<keyof T, string>
87+
// Whether the attrs option is defined
88+
export type HasDefinedAttrs<T> = Equal<keyof T, string> extends true
89+
? false
90+
: true
8991
/**
9092
* For extending allowed non-declared props on components in TSX
9193
*/
@@ -192,9 +194,9 @@ export type SetupContext<
192194
Attrs extends AttrsType = Record<string, unknown>
193195
> = E extends any
194196
? {
195-
attrs: noAttrsDefine<Attrs> extends true
196-
? Data
197-
: UnwrapAttrsType<NonNullable<Attrs>>
197+
attrs: HasDefinedAttrs<Attrs> extends true
198+
? UnwrapAttrsType<NonNullable<Attrs>>
199+
: Data
198200
slots: UnwrapSlotsType<S>
199201
emit: EmitFn<E>
200202
expose: (exposed?: Record<string, any>) => void

packages/runtime-core/src/componentOptions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ declare const AttrSymbol: unique symbol
421421
export type AttrsType<T extends Record<string, any> = Record<string, any>> = {
422422
[AttrSymbol]?: T
423423
}
424+
// extract props and event types from components
425+
export type ExtractPropsAndEvents<
426+
T extends abstract new (...args: any) => any
427+
> = InstanceType<T>['$props']
424428

425429
export type UnwrapAttrsType<
426430
Attrs extends AttrsType,

packages/runtime-core/src/componentPublicInstance.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {
2+
AllowedComponentProps,
23
ComponentInternalInstance,
34
Data,
4-
noAttrsDefine,
5+
HasDefinedAttrs,
56
getExposeProxy,
67
isStatefulComponent
78
} from './component'
@@ -211,9 +212,9 @@ export type ComponentPublicInstance<
211212
S extends SlotsType = {},
212213
Attrs extends AttrsType = Record<string, unknown>, // Attrs type extracted from attrs option
213214
// AttrsProps type used for JSX validation of attrs
214-
AttrsProps = noAttrsDefine<Attrs> extends true // if attrs is not defined
215-
? {} // no JSX validation of attrs
216-
: Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)> // exclude props from attrs, for JSX validation
215+
AttrsProps = HasDefinedAttrs<Attrs> extends true // if attrs is defined
216+
? Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)> // exclude props from attrs, for JSX validation
217+
: {} // no JSX validation of attrs
217218
> = {
218219
$: ComponentInternalInstance
219220
$data: D
@@ -222,9 +223,9 @@ export type ComponentPublicInstance<
222223
? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults> & AttrsProps
223224
: P & PublicProps & AttrsProps
224225
>
225-
$attrs: noAttrsDefine<Attrs> extends true
226-
? Data
227-
: Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)>
226+
$attrs: HasDefinedAttrs<Attrs> extends true
227+
? AttrsProps & AllowedComponentProps
228+
: Data
228229
$refs: Data
229230
$slots: UnwrapSlotsType<S>
230231
$root: ComponentPublicInstance | null

packages/runtime-core/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ export type {
247247
ComputedOptions,
248248
RuntimeCompilerOptions,
249249
ComponentInjectOptions,
250-
AttrsType
250+
AttrsType,
251+
ExtractPropsAndEvents
251252
} from './componentOptions'
252253
export type { EmitsOptions, ObjectEmitsOptions } from './componentEmits'
253254
export type {

0 commit comments

Comments
 (0)