vue-tsx-support
vue-tsx-support copied to clipboard
Generics not working for component definitions when upgrading to version 3+
If I upgrade to version 3.2.0 from 2.3.3, generics stop working in my components
import * as tsx from 'vue-tsx-support';
import { Prop, Component } from 'vue-property-decorator';
interface IMyProps<TType> {
items: TType[];
}
@Component
export default class AList<TType> extends tsx.Component<IMyProps<TType>> {
// ...
}
With 2.3.3
I can use AList in other .tsx files and provide any kind of array for items
and it will works
With 3.2.0
all my other components using AList are giving me error because TType
of AList is inferred to be of type unknown
instead
This code works with [email protected] (with [email protected] or 4.3.5) Can you show me a minimal reproduction ?
import { Component, Prop } from "vue-property-decorator";
import * as vuetsx from "vue-tsx-support";
interface ListProp<T> {
items: T[];
}
@Component
class AList<T> extends vuetsx.Component<ListProp<T>> {
@Prop()
items!: T[];
}
const items: number[] = [1, 2, 3];
<AList items={items} />;
BTW, you can obtain typed component like below.
const ANumberList = AList as new () => AList<number>;
<ANumberList items={[1, 2, 3]} />;
Thank you for the answer - I'll see if I can followup with a minimal reproduction example.
Hello @wonderful-panda and @LolliDepp I can confirm generic types are not correctly working. See the screenshot.
As you can see, items
is (incorrectly) typed as (JSX attribute) items: (string | number)[]
, but it should be typed as number[]
as we specify the generic type parameter number
. The array [1, 2, 3, '2']
is accepted while it should not. This also leads to other errors when extending parent classes. I cannot provide the code to reproduce the error with the class, but the TypeScript server indicates :
The expected type comes from property 'items' which is declared here on type 'IntrinsicAttributes & (CombinedTsxComponentAttrs<{}, ListProp<string | number>, {}, {}, InnerScopedSlots<{}>, true> & {})'
Everything works as expected in
v2.3.2
.
Here is the code to reproduce (based on @wonderful-panda, but I think you did not check correctly the type, happens :)) :
/* eslint-disable max-classes-per-file */
import { Component, Prop } from 'vue-property-decorator';
import * as vuetsx from 'vue-tsx-support';
interface ListProp<T> {
items: T[];
}
@Component
class AList<T extends number | string> extends vuetsx.Component<
ListProp<T>,
{}
> {
@Prop()
items!: T[];
}
@Component
class Test extends vuetsx.Component<{}> {
render() {
const items = [1, 2, 3, '2'];
// enable this to check TypeScript error
// const items = [1, 2, 3, '2', new Date()];
return <AList<number> items={items} />;
}
}
function test<T extends string | number>(items: T[]) {
return false;
}
test<number>([1, 2, 'sd']);
Please do not hesitate to ask if you need more details.