Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): export type for VDataTable headers #21052

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

J-Sek
Copy link
Contributor

@J-Sek J-Sek commented Mar 3, 2025

Description

followup to #16680

It seems to be one of the common requests on Discord.

Markup:

<template>
  <v-app>
    <v-container>
      <v-data-table :headers="headers" :items="items" class="elevation-5" />
    </v-container>
  </v-app>
</template>

<script setup lang="ts">
  // Add following entry to import map on VPlay:
  // "vuetify/components/VDataTable": "https://cdn.jsdelivr.net/npm/vuetify@latest/lib/components/VDataTable/index.d.mts",

  import type { VDataTableHeader } from 'vuetify/components/VDataTable'

  const headers: VDataTableHeader[] = [
    { title: 'Name', value: 'name' },
    { title: 'Age', value: 'age' },
    { text: 'Email', value: 'email' },
  ]

  const items = [
    { name: 'John Doe', age: 25, email: '[email protected]' },
    { name: 'Jane Smith', age: 30, email: '[email protected]' },
    { name: 'Alice Johnson', age: 22, email: '[email protected]' },
  ]
</script>

@J-Sek J-Sek added T: bug Functionality that does not work as intended/expected C: VDataTable typescript labels Mar 3, 2025
@J-Sek J-Sek self-assigned this Mar 3, 2025
@J-Sek
Copy link
Contributor Author

J-Sek commented Mar 3, 2025

It does not really underline the text in the example for me (open in local fork & playground), but I recently nuked my local environment and switched from VSCode to VSCodium so maybe it's just my machine. It would be great to have it verified by someone else. Nevermind, verified:

image

@J-Sek J-Sek requested a review from KaelWD March 3, 2025 18:52
@BalagePMI
Copy link

Note that not only VDataTableHeader should be exported, but a dozen other types used by VDataTableHeader, such as SelectItemKey, and the function definitions, etc.

@J-Sek
Copy link
Contributor Author

J-Sek commented Mar 4, 2025

@BalagePMI , I get it would be convenient, but Lookup Types seem to enable deeper access. Actually I just noticed the type I am trying to explicitly export is also available through this technique - making this PR more like enhancement than a fix.

const actionTitle = ref<VDataTable['$props']['headers'][0]['title'] | null>(null)
const titleLowercase = computed(() => actionTitle.value?.toLowerCase())

// can be assigned to an alias
type VDataTableHeader = VDataTable['$props']['headers']

const headers: VDataTableHeader = [
  { title: 'Name', value: 'name' },
  { title: 'Age', value: 'age' },
  { text: 'Email', value: 'email' }, // should underline `text`
]

Demo

@J-Sek J-Sek added T: enhancement Functionality that enhances existing features and removed T: bug Functionality that does not work as intended/expected labels Mar 4, 2025
@BalagePMI
Copy link

For me, it doesn't work:

import { VDataTable } from 'vuetify/components'

export type DataTableHeader = VDataTable['$props']['headers']

And using it:

      const def : DataTableHeader = {
        key: header.key,
        title: header.title ?? i18n.t(props.itemCode + '.columns.' + header.key + '.title'),
        align: header.align ?? 'start',
        sortable: header.sortable ?? false
      }
      if (header.maxWidth) {
        def.maxWidth = convertWidth(header.maxWidth, undefined)
      }
      def.width = convertWidth(header.width, def.maxWidth)
      console.log('header', def.key, def)
      return def
    })]
})

marks key, maxWidth, width as not in type, because DataTableHeader is identified as any.

Also, this access of type looks as bad as declaring my own as it digs deeply into a structure.

@J-Sek
Copy link
Contributor Author

J-Sek commented Mar 4, 2025

You need [0] to get to single header type. Also scoping the import to vuetify/components/VDataTable might help IDE avoid loading all the types and prevent TS hiccups. (but you might still need to run nuxt prepare if you rely on auto-imports)

I cannot extract single header locally, because of DeepReadonly<..> wrapper in the generated types for props. The root cause of might be hard to track.. IDE, TypeScript or one of IDE extensions. Explicit export would definitely help eliminate this issue.

Weird that it works on VPlay demo just fine:

image

@J-Sek
Copy link
Contributor Author

J-Sek commented Mar 4, 2025

I cannot extract single header locally, because of DeepReadonly<..> wrapper in the generated types for props

Workaround:

import type { VDataTable } from 'vuetify/components/VDataTable'

export type DataTableHeaders = VDataTable['$props']['headers'] & {}
export type DataTableHeader = DataTableHeaders[0] // take single header

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: VDataTable T: enhancement Functionality that enhances existing features typescript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants