Missing base props in generic component
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;
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