Skip to content

Type Interference for Props is not working with wrapped setup methods #11962

Open
@jleifeld

Description

@jleifeld

Vue version

3.5.6

Link to minimal reproduction

https://play.vuejs.org/#eNqdU21r2zAQ/iuHPiUlxJTtU5YEthHGxmhNkn4TDMc+x25lSeilSTH+7ztLTurB6EaFEae7R4+ee3HLPms9f/bIFmxpc1NrByKTxxVnznK25jJJ4BtKNJmAk8k0NOgqVUCpDFh0XsOpqvMKbKW8KKCWJRpwFYI2SltwLxot5MoYzJ144bL0Mne1koFsmW7v090Mdpv9Q/pru9k9/NyvJ4F2AZPAsICAmcJq/Qds+i8AtFwCGOIyMirlsuOSSzxrZRwUWGZeuAgbmILdr+zONwc0KblH3n71CS0ghmfjwMC3gNuruwtW3Iek+qwnUXhQPHBTkfdVbS9VPGB4R5XDQ3DwLhQ1lBdlTpYFqRyclHmq5TGy5EpawiFtq5jSfJTIpwgaKtJSLUjbNIi7PE/fiDC5iaovcv9TayaLwGLfLQpuktCrZRInkqaQDg4bLTKHdAJYVrfrth33CbpumZC3vzaCshkNMmko6+P80SpJcx7y4CxXja4FmnvdzyMN+7XTnGVCqNOP4HPG49BRulNh/vQX/6M99z7OUoMWzTNydo25zBzRxfBmd4dnsq/BRhVeEPqN4BatEr7XGGFfvCxI9ggX1H5v+rGm1u3t5uxQ2ktSvdDXOeSMfvavb6T+KvfD/GO4R71g3W/jgV88

Steps to reproduce

Look at these DTS test: 348d9c6

This should be green but it is not working.

What is expected?

Typescript supports type inference in cases like this. Here is another, non-Vue example which works:

type exampleProps<T> = {
    setup: (props: { multiplier: string }) => T
}

function defineComponent<T>(component: exampleProps<T>) {
    return component;
}

function createExtendableSetup<PROPS, SETUP_RESULT>(setupFn: (props: PROPS) => SETUP_RESULT) {
    return setupFn;
}

const testWithCreateExtendableSetup = defineComponent({
    setup: createExtendableSetup((props /* PROPS is typed correctly */) => {
        // This is a correct inferred string value, even when used in the return method
        const foo = props.multiplier;

        return {
            foo
        }
    }),
})

So Vue should also be able to inference the "props" types correctly.

What is actually happening?

The inference is broken when a wrapping method is used. See the Github Commit example or the Playground example.

System Info

No response

Any additional comments?

We want to write a extension system for Vue components and therefore need to wrap the setup method like this:

setup: createExtendableSetup('originalComponent', (props) => {
      const count = ref(1);
      const multipliedCount = computed(() => count.value * props.multiplier);

      return {
          count,
          multipliedCount,
      };
  }),

Our implementation is working fine. The only problem is that the types of the arguments are getting lost.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions