Skip to content

Commit 7f374a3

Browse files
danyadevdanil.nemov
authored andcommitted
fix(types): make generics with runtime props in defineComponent work
1 parent cdffaf6 commit 7f374a3

File tree

2 files changed

+89
-12
lines changed

2 files changed

+89
-12
lines changed

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

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ describe('function syntax w/ emits', () => {
14021402
describe('function syntax w/ runtime props', () => {
14031403
// with runtime props, the runtime props must match
14041404
// manual type declaration
1405-
defineComponent(
1405+
const Comp1 = defineComponent(
14061406
(_props: { msg: string }) => {
14071407
return () => {}
14081408
},
@@ -1411,7 +1411,34 @@ describe('function syntax w/ runtime props', () => {
14111411
},
14121412
)
14131413

1414+
// @ts-expect-error bar isn't specified in props definition
14141415
defineComponent(
1416+
(_props: { msg: string }) => {
1417+
return () => {}
1418+
},
1419+
{
1420+
props: ['msg', 'bar'],
1421+
},
1422+
)
1423+
1424+
defineComponent(
1425+
(_props: { msg: string; bar: string }) => {
1426+
return () => {}
1427+
},
1428+
{
1429+
props: ['msg'],
1430+
},
1431+
)
1432+
1433+
expectType<JSX.Element>(<Comp1 msg="1" />)
1434+
// @ts-expect-error msg type is incorrect
1435+
expectType<JSX.Element>(<Comp1 msg={1} />)
1436+
// @ts-expect-error msg is missing
1437+
expectType<JSX.Element>(<Comp1 />)
1438+
// @ts-expect-error bar doesn't exist
1439+
expectType<JSX.Element>(<Comp1 msg="1" bar="2" />)
1440+
1441+
const Comp2 = defineComponent(
14151442
<T extends string>(_props: { msg: T }) => {
14161443
return () => {}
14171444
},
@@ -1420,7 +1447,36 @@ describe('function syntax w/ runtime props', () => {
14201447
},
14211448
)
14221449

1450+
// @ts-expect-error bar isn't specified in props definition
14231451
defineComponent(
1452+
<T extends string>(_props: { msg: T }) => {
1453+
return () => {}
1454+
},
1455+
{
1456+
props: ['msg', 'bar'],
1457+
},
1458+
)
1459+
1460+
defineComponent(
1461+
<T extends string>(_props: { msg: T; bar: T }) => {
1462+
return () => {}
1463+
},
1464+
{
1465+
props: ['msg'],
1466+
},
1467+
)
1468+
1469+
expectType<JSX.Element>(<Comp2 msg="1" />)
1470+
expectType<JSX.Element>(<Comp2<string> msg="1" />)
1471+
// @ts-expect-error msg type is incorrect
1472+
expectType<JSX.Element>(<Comp2 msg={1} />)
1473+
// @ts-expect-error msg is missing
1474+
expectType<JSX.Element>(<Comp2 />)
1475+
// @ts-expect-error bar doesn't exist
1476+
expectType<JSX.Element>(<Comp2 msg="1" bar="2" />)
1477+
1478+
// Note: generics aren't supported with object runtime props
1479+
const Comp3 = defineComponent(
14241480
<T extends string>(_props: { msg: T }) => {
14251481
return () => {}
14261482
},
@@ -1431,37 +1487,58 @@ describe('function syntax w/ runtime props', () => {
14311487
},
14321488
)
14331489

1434-
// @ts-expect-error string prop names don't match
14351490
defineComponent(
1436-
(_props: { msg: string }) => {
1491+
// @ts-expect-error bar isn't specified in props definition
1492+
<T extends string>(_props: { msg: T }) => {
14371493
return () => {}
14381494
},
14391495
{
1440-
props: ['bar'],
1496+
props: {
1497+
bar: String,
1498+
},
14411499
},
14421500
)
14431501

14441502
defineComponent(
1445-
(_props: { msg: string }) => {
1503+
// @ts-expect-error generics aren't supported with object runtime props
1504+
<T extends string>(_props: { msg: T; bar: T }) => {
14461505
return () => {}
14471506
},
14481507
{
14491508
props: {
1450-
// @ts-expect-error prop type mismatch
1451-
msg: Number,
1509+
msg: String,
14521510
},
14531511
},
14541512
)
14551513

1456-
// @ts-expect-error prop keys don't match
1514+
expectType<JSX.Element>(<Comp3 msg="1" />)
1515+
// @ts-expect-error generics aren't supported with object runtime props
1516+
expectType<JSX.Element>(<Comp3<string> msg="1" />)
1517+
// @ts-expect-error msg type is incorrect
1518+
expectType<JSX.Element>(<Comp3 msg={1} />)
1519+
// @ts-expect-error msg is missing
1520+
expectType<JSX.Element>(<Comp3 />)
1521+
// @ts-expect-error bar doesn't exist
1522+
expectType<JSX.Element>(<Comp3 msg="1" bar="2" />)
1523+
1524+
// @ts-expect-error string prop names don't match
14571525
defineComponent(
1458-
(_props: { msg: string }, ctx) => {
1526+
(_props: { msg: string }) => {
1527+
return () => {}
1528+
},
1529+
{
1530+
props: ['bar'],
1531+
},
1532+
)
1533+
1534+
defineComponent(
1535+
(_props: { msg: string }) => {
14591536
return () => {}
14601537
},
14611538
{
14621539
props: {
1463-
msg: String,
1464-
bar: String,
1540+
// @ts-expect-error prop type mismatch
1541+
msg: Number,
14651542
},
14661543
},
14671544
)

packages/runtime-core/src/apiDefineComponent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export function defineComponent<
157157
ctx: SetupContext<E, S>,
158158
) => RenderFunction | Promise<RenderFunction>,
159159
options?: Pick<ComponentOptions, 'name' | 'inheritAttrs'> & {
160-
props?: (keyof Props)[]
160+
props?: (keyof NoInfer<Props>)[]
161161
emits?: E | EE[]
162162
slots?: S
163163
},

0 commit comments

Comments
 (0)