Subscribe on changes!

Missing base props in generic component

avatar
Jun 19th 2023

Vue version

3.3.4

Link to minimal reproduction

https://github.com/s-montigny-desautels/vue3.3-issues

Steps to reproduce

$ pnpm install

Look for the error in file BugTSXClassUnknownProperty.tsx and file BugTSXClassUnknownProperty.vue

What is expected?

No type errors for ref, class and style properties in .vue file when using .tsx file. No type errors for class and style properties in .tsx file when using .tsx file.

What is actually happening?

The class and style props and not present in the typing. This cause a ts error. For the .vue file, the ref is not present also.

System Info

System:
    OS: Linux 6.3 Fedora Linux 38 (Workstation Edition)
    CPU: (16) x64 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
    Memory: 21.57 GB / 31.05 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 18.14.2 - ~/.nvm/versions/node/v18.14.2/bin/node
    Yarn: 1.22.19 - ~/.local/share/pnpm/yarn
    npm: 9.5.0 - ~/.nvm/versions/node/v18.14.2/bin/npm
  Browsers:
    Chrome: 114.0.5735.133
    Firefox: 114.0

Any additional comments?

When looking in the type definition of defineComponent, the type returns a function instead of the DefineComponent type. This is probably expected so the generic can work. I think some base props should be added, something like:

type BaseProps = {
  class: any;
  style: any;
  ref: any;
  ... other
}

declare function defineComponent = (setup: (...)) => (props: Props & EmitsToProps<E> & BaseProps) => any;
avatar
Jun 27th 2023

It's a language-tools issue.

avatar
Jun 27th 2023

It's in tsx files. Isn't the language-tools for vue files only?

avatar
Jun 27th 2023

Hmmm, maybe u r right! 😂

avatar
Nov 6th 2023

There seems to be a problem with the type returned by the defineComponent function. The example is as follows:

const TestCom = defineComponent((props) => {
  // ...
}, {
  props: {
    name: {
      type: String,
      required: true,
    },
    size: {
      type: Number,
      default: 16,
    },
  }
});

The inferred type of TestCom is:

const TestCom: (props: {
    name: string;
    size: number;
} & {}) => any

The props part type is:

// inferred type
(props: {
    name: string;
    size: number;
}) => {
  // ...
}

The props type is correct, the TestCom type is wrong, the TestCom type should be:

const TestCom: (props: {
    name: string;
    size?: number;
} & {}) => any

defineComponent function signature

export declare function defineComponent<Props extends Record<string, any>, E extends EmitsOptions = {}, EE extends string = string, S extends SlotsType = {}>(setup: (props: Props, ctx: SetupContext<E, S>) => RenderFunction | Promise<RenderFunction>, options?: Pick<ComponentOptions, 'name' | 'inheritAttrs'> & {
    props?: (keyof Props)[];
    emits?: E | EE[];
    slots?: S;
}): (props: Props & EmitsToProps<E>) => any;
export declare function defineComponent<Props extends Record<string, any>, E extends EmitsOptions = {}, EE extends string = string, S extends SlotsType = {}>(setup: (props: Props, ctx: SetupContext<E, S>) => RenderFunction | Promise<RenderFunction>, options?: Pick<ComponentOptions, 'name' | 'inheritAttrs'> & {
    props?: ComponentObjectPropsOptions<Props>;
    emits?: E | EE[];
    slots?: S;
}): (props: Props & EmitsToProps<E>) => any;

There seems to be no distinction between internal and external types of components