core
core copied to clipboard
defineComponent generic type error
Version
3.2.21
Reproduction link
Steps to reproduce
The type of the parameter props of the setup function and the generic type of DefineComponent<Props>
should not be the same.
// overload 1: direct setup function
// (uses user defined props interface)
export function defineComponent<Props, RawBindings = object>(
setup: (
props: Readonly<Props>,
ctx: SetupContext
) => RawBindings | RenderFunction
): DefineComponent<Props, RawBindings>
What is expected?
interface TestProps {
name: string;
age?: number;
}
export const Test = defineComponent<TestProps>(function Test(props) {
return () => {
return <div>{props.name}</div>;
};
});
<Test />
The volar should prompt whether the prop name is required.
What is actually happening?
The volar don't prompt.
Would it be better?
type NonUndefinedable<T> = T extends undefined ? never : T;
export type DefinePropsToOptions<T> = {
[K in keyof T]-?: Record<string, never> extends Pick<T, K>
? { type: PropType<NonUndefinedable<T[K]>> }
: { type: PropType<T[K]>; required: true };
};
export function defineComponent<Props, RawBindings = object>(
setup: (
props: Readonly<Props>,
ctx: SetupContext
) => RawBindings | RenderFunction
): DefineComponent<DefinePropsToOptions<Props>, RawBindings>
Declare a component like this, props are props that default to the browser’s native tags. Props cannot get name and age...😟 It seems to be inconsistent with the expected behavior, maybe I misunderstood it?
Declare a component like this, props are props that default to the browser’s native tags. Props cannot get name and age...😟 It seems to be inconsistent with the expected behavior, maybe I misunderstood it?
I think you should define props.
interface TestProps {
name: string;
age?: number;
}
export const Test = defineComponent<TestProps>(function Test(props) {
return () => {
return <div>{props.name}</div>;
};
});
Test.props = ['name', 'age']
Declare a component like this, props are props that default to the browser’s native tags. Props cannot get name and age...😟 It seems to be inconsistent with the expected behavior, maybe I misunderstood it?
I think you should define props.
interface TestProps { name: string; age?: number; } export const Test = defineComponent<TestProps>(function Test(props) { return () => { return <div>{props.name}</div>; }; }); Test.props = ['name', 'age']
get!
像这样声明一个组件,props 是默认为浏览器原生标签的 props。道具无法获取名称和年龄...😟这似乎与预期的行为不一致,也许我误解了?
我认为你应该定义道具。
interface TestProps { name: string; age?: number; } export const Test = defineComponent<TestProps>(function Test(props) { return () => { return <div>{props.name}</div>; }; }); Test.props = ['name', 'age']
But,why? we should have a better way or api
像这样声明一个组件,props 是默认为浏览器原生标签的 props。道具无法获取名称和年龄...😟这似乎与预期的行为不一致,也许我误解了?
我认为你应该定义道具。
interface TestProps { name: string; age?: number; } export const Test = defineComponent<TestProps>(function Test(props) { return () => { return <div>{props.name}</div>; }; }); Test.props = ['name', 'age']
But,why? we should have a better way or api
因为TS是不参与运行时的。在运行时会丢失所有类型的定义,就无法知道定义了哪些props。
@yinxulai