Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tsx): add support for passing generics to child components #11478

Open
wants to merge 14 commits into
base: minor
Choose a base branch
from

Conversation

Procrustes5
Copy link
Contributor

@Procrustes5 Procrustes5 commented Aug 2, 2024

Issue

close #11374

Description

Based on the above issue, changed it to be able to use generics on defineComponent.

const Comp = defineComponent(
  <T extends Record<string, any>>(props: { msg: string; list: T[] }) => {

    console.log(`list`, props.list)
    return () => {
      return <div>
      <h2>{props.msg}</h2>
      {
        props.list.map(t => <p>{t.name}</p>)
      }
      </div>
    }
  },
  {
    props: ['msg', 'list']
  }
)

const Demo = defineComponent(() => {
    const list = ref([
      { name: 'Tom' },
      { name: 'Jack' },
    ])

    return () => {
      
      return <div>
        <Comp<{ name: string }> msg="hello" list={list.value} /> // Enable to use Generics on defineComponent
      </div>
    }
})

I'm not sure if this direction is right in the first place because a bigger change has been made than I thought.
This is my first time writing a PR here, so there can be a lot of mistakes. I want to continue contributing in the future, please advise me.

@Pentadome
Copy link
Contributor

Oh nice job 👍

Copy link

netlify bot commented Aug 16, 2024

Deploy Preview for vue-sfc-playground failed.

Name Link
🔨 Latest commit 15a5269
🔍 Latest deploy log https://app.netlify.com/sites/vue-sfc-playground/deploys/66be9c2914baa600083692d8

@Procrustes5
Copy link
Contributor Author

CI fails with updating branch. How can I fix it?

@edison1105 edison1105 linked an issue Aug 16, 2024 that may be closed by this pull request
Copy link

github-actions bot commented Aug 16, 2024

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 98.8 kB (+38 B) 37.4 kB (+18 B) 33.7 kB (-15 B)
vue.global.prod.js 156 kB (+38 B) 57.2 kB (+15 B) 50.9 kB (-29 B)

Usages

Name Size Gzip Brotli
createApp 54.2 kB 21 kB 19.1 kB
createSSRApp 58.1 kB 22.6 kB 20.6 kB
defineCustomElement 58.8 kB (+42 B) 22.5 kB (+15 B) 20.5 kB (+6 B)
overall 67.8 kB 26 kB 23.7 kB

@edison1105 edison1105 requested a review from pikax August 16, 2024 01:29
@@ -1704,5 +1706,104 @@ describe('api: options', () => {
`Computed property "foo" is already defined in Data.`,
).toHaveBeenWarned()
})

test('defineComponent with generic', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the tests are related to types should be placed in packages/dts-test/defineComponent.test-d.tsx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edison1105
thank you!
I moved it to defineComponent.test-d.tsx!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still not quite right, you need to refer to the exist test cases in the defineComponent.test-d.tsx file to add new test cases. Check the type only, do not test the render result

Copy link
Contributor Author

@Procrustes5 Procrustes5 Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edison1105
Modified! It's my insufficient understanding. Would you review the changes once more?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those test cases seem not to be related generics. you should refer to this test case

describe('function syntax w/ generics', () => {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edison1105
My understanding of the tests was completely lacking. What do you think of this revision?
I'd appreciate your review.

Copy link

pkg-pr-new bot commented Aug 26, 2024

commit: e46dfdd

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@11478

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@11478

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@11478

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@11478

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@11478

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@11478

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@11478

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@11478

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@11478

vue

pnpm add https://pkg.pr.new/vue@11478

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@11478

Open in Stackblitz

extend({ name: options.name }, extraOptions, { setup: options }))()
export function defineComponent(options: unknown): any {
const comp = isFunction(options)
? { setup: options, name: options.name }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this change? It doesn't seem to be related to types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edison1105
The original code had logic to convert function components into objects, but I changed the runtime behavior using Proxy. This was intended to handle props when using Generic Components in TSX.

As you pointed out, this isn't related to types. I realized that by removing extraOptions in this modification, I might have eliminated the ability to extend types.

I'm planning to revert these changes, but is my thought process correct?

Thank you for reviewing multiple times.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intended to handle props when using Generic Components in TSX.

  • I am not sure about this, keep this, waiting for other team members' review

  • It looks like the test case is incorrect because it still passes without the changes in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for review!

It looks like the test case is incorrect because it still passes without the changes in this PR.

Does the fact that the test passes without this change mean that the following writing style already exists?

// Test GenericComp directly with correct props
expectType<JSX.Element>(
<GenericComp<{ name: string }> msg="hello" list={[{ name: 'Alice' }]} />,
)

Or is there a possibility that the original type checking was loose and designed not to throw errors regardless of the writing style?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to use generics in TSX
4 participants