Search code examples
javascripttypescriptvue.js

How do I fix (or ignore) a TypeScript error that's inside a HTML template?


I have the following HTML template in a VueJS-2 component:

<template>
  <div>
    <v-data-table
      :headers="headers"
      :items="items"
      :caption="label"
      dense
      hide-default-footer
      hide-default-header
    >
      <template v-slot:item.name="props">
        <MiniTextField
          :value="props.item.name"
          dense
          single-line
          hide-details
          prepend-icon="mdi-account"
          @change="(newValue) => crewEntryUpdated(newValue, props)"
        ></MiniTextField>
      </template>
    </v-data-table>
  </div>
</template>

The following line gives an error:

@change="(newValue) => crewEntryUpdated(newValue, props)"

The error is:

src/components/CrewTable.vue:18:21 - error TS7006: Parameter 'newValue' implicitly has an 'any' type.

18           @change="(newValue) => crewEntryUpdated(newValue, props)"
                       ~~~~~~~~

Adding a type-hint to the function is invalid syntax and breaks the compilation. So the following does not work. It leads to:

7:54:44 AM [vite] Internal server error: Unexpected token, expected "," (1:395)
  Plugin: vite:vue2
  File: /workspaces/frontend/src/components/CrewTable.vue:1:395
  16 |            hide-details
  17 |            prepend-icon="mdi-account"
  18 |            @change="(newValue: string) => crewEntryUpdated(newValue, props)"
     |                   ^
  19 |          ></MiniTextField>
  20 |        </template>

Changing it to a multi-line code-block breaks the event-handler silently. TS no longer complains, but the handler is also not called. So the following also does not work:

          @change="
            // @ts-ignore
            (newValue) => crewEntryUpdated(newValue, props)
          "

I don't want to ignore the whole file. So how can I modify my code to make TS happy?


Solution

  • Vue SFC aren't spec-compliant, their support depends on a tool. The use of TypeScript in is more exotic and can cause problems.

    It makes sense to write all scripts in <script> section, this makes a template more readable and allows for proper typing:

    @change="onChange"
    

    Otherwise this is avoided by using local $event value:

    @change="crewEntryUpdated($event, props)"