-
Notifications
You must be signed in to change notification settings - Fork 39
Open
Description
Creating a component constructor from a generic function that has any properties of those types will not compile in markup. It produces the following compiler error based on the provided example:
${projectDir}/render/app/components/test.tsx:54:36: No overload matches this call.
Overload 1 of 3, '(options?: ThisTypedComponentOptionsWithArrayProps<{ _tsxattrs: TsxComponentAttrs<{ options: T[]; } & { value?: V | undefined; }, {}, {}>; } & Vue & { innerValue: number | undefined; } & { onChange(value: number): void; } & { ...; } & { ...; }, object, object, object, never> | undefined): CombinedVueInstance<...>', gave the following error.
Type '{ label: string; value: number; }[]' is not assignable to type 'T[]'.
Type '{ label: string; value: number; }' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to '{ label: string; value: number; }'.
Overload 2 of 3, '(options?: ThisTypedComponentOptionsWithRecordProps<{ _tsxattrs: TsxComponentAttrs<{ options: T[]; } & { value?: V | undefined; }, {}, {}>; } & Vue & { innerValue: number | undefined; } & { onChange(value: number): void; } & { ...; } & { ...; }, object, object, object, object> | undefined): CombinedVueInstance<...>', gave the following error.
Type '{ label: string; value: number; }[]' is not assignable to type 'T[]'.
Overload 3 of 3, '(options?: ComponentOptions<{ _tsxattrs: TsxComponentAttrs<{ options: T[]; } & { value?: V | undefined; }, {}, {}>; } & Vue & { innerValue: number | undefined; } & { onChange(value: number): void; } & { ...; } & { ...; }, ... 4 more ..., Record<...>> | undefined): CombinedVueInstance<...>', gave the following error.
Type '{ label: string; value: number; }[]' is not assignable to type 'T[]'. [TS2769]
Example:
import { PropOptions, PropType, VNode } from "vue";
import * as tsx from "vue-tsx-support";
const options = [
{ label: "Option One", value: 1 },
{ label: "Option Two", value: 2 },
{ label: "Option Three", value: 3 },
];
type Option = typeof options[number];
function select<T, V extends number|string>(predicate: (option: T) => [ string, V ]) {
return tsx.component({
name: "Select",
props: {
value: { default: undefined } as PropOptions<V>,
options: { type: Array as PropType<T[]>, required: true },
},
data: function () {
return {
innerValue: this.value as V|undefined,
};
},
computed: {
label(): string {
const value = this.options.find(option => predicate(option)[1] === this.innerValue);
return value ? predicate(value)[0] : "Required";
},
},
methods: {
onChange(value: V) {
this.innerValue = value;
this.$emit("change", value);
},
},
render(): VNode {
return (<select value={this.innerValue} onChange={value => this.onChange(value as any)}>{
this.options.map(option => (
<option value={predicate(option)[1]}>{predicate(option)[0]}</option>
))
}</select>);
},
});
}
// OptionSelect is typeof Select<Option, number>;
const OptionSelect = select((option: Option) => [ option.label, option.value ]);
// @vue/component
const test = tsx.component({
name: "test",
render(): VNode {
return (<div><OptionSelect options={options}/></div>);
},
});
type test = InstanceType<typeof test>;
export default test;Metadata
Metadata
Assignees
Labels
No labels