Open SniperJoe opened 2 years ago
Looking into this, it seems the (type) definition of renderList
helper function (here aliased as _renderList
) seems to be the reason for this behaviour.
There are multiple type overloads for renderList
(selectively quoting from <vue-next>/packages/runtime-core/src/helpers/renderList.ts
):
/**
* v-for array
*/
export function renderList<T>(
source: T[],
renderItem: (value: T, index: number) => VNodeChild
): VNodeChild[]
/**
* v-for object
*/
export function renderList<T>(
source: T,
renderItem: <K extends keyof T>(
value: T[K],
key: K,
index: number
) => VNodeChild
): VNodeChild[]
The second parameter of the renderItem
function can be a an index (with type number
, when source
is an array) or a key (with type string | number | symbol
, when source
is an object).
It seems compiling the template happens without any type knowledge about the Vue component instance, i.e. we don't know the type of bookmakersVote
. As a result, the TS compiler does not know it should use the "array" definition of renderList
. Instead the "object" definition applies, as it is a more generic overload.
Because of this, bkIndex
in your example to the TS compiler has the type string | number | symbol
, not all of which the modulo operator can be applied to.
I'm new to the Vue template compiler and vue-loader, but to me there seem to be some possible solutions for this:
(bk, bkIndex: any)
as the parameter list for the renderItem
function. This avoids the type check the TS compiler complained about. This might be possible without changing too much of the Vue compiler code.<template>
part altogether.<script>
part to the <template>
compilation part. We could then annotate _ctx.bookmakersVote
with the correct type (DataTypes.BookmakerVoteData[]
or at least any[]
), which helps the TS compiler to pick up the right overloaded version of renderList
, correctly inferring the type of bkIndex
to be number
. This looks like the most expensive approach.for me this was happening only in production, we're using webpack. I was able to quell the error by adding as number to the usage of the index.
Version
16.8.1
Reproduction link
github.com
Steps to reproduce
Given I have an array in my component:
and I'm using it in the template:
What is expected?
Successful compilation
What is actually happening?
vue-loader compiles it into:
ts-loader (v 9.2.6) refuses to compile that. It throws error:
Temporary fix is to wrap the index: