导入 Vuetify3 v-data-table 的 DataTableHeader typescript 类型

YYY*_*YYY 6 typescript vue.js vuetify.js vuejs3 vuetifyjs3

我无法导入 v-data-table 标头的类型定义 DataTableHeader。目前,我是这样写的:

import { DataTableHeader } from 'vuetify/types';
Run Code Online (Sandbox Code Playgroud)

在 TypeScript 错误中,它说

找不到模块“vuetify/types”或其相应的类型声明。

有谁知道这个问题的解决方案?

Mor*_*ler 24

DataTableHeaders 类型当前未导出(从 Vuetify 3.5.5 开始)。我的猜测是,这将来会改变,但与此同时,您仍然可以从VDataTable.

Vuetify 3.5(当前)

从 v3.3 开始,标头是深度只读的。我们可以撤消只读,但不能不更改类型,这使其与初始 DataTableHeader 声明不兼容,并且在分配给 v-data-table 时需要额外的类型断言。

因此,如果您知道声明后不会更改标头,我将仅使用只读声明:

import type { VDataTable } from 'vuetify/components'

type ReadonlyHeaders = VDataTable['$props']['headers']

const headers: ReadonlyHeaders = [...]
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个数组类型 ( DataTableHeader[])。如果您想要项目类型,您可以进一步展开它:

import type { VDataTable } from 'vuetify/components'

type ReadonlyHeaders = VDataTable['$props']['headers']
type UnwrapReadonlyArray<A> = A extends Readonly<Array<infer I>> ? I : never;
type ReadonlyDataTableHeader = UnwrapReadonlyArrayType<ReadonlyHeaders>;

const headers: ReadonlyDataTableHeader[] = [...]
Run Code Online (Sandbox Code Playgroud)

UnwrapReadonlyArray实用程序类型解开只读数组并丢弃可能的undefined

然而,事实证明这需要在 Vuetify 版本之间进行更新,而数组版本则不需要。如果可能,请坚持使用阵列版本以避免维护。


如果您需要在声明后更改标头,您可以使用另一个实用程序类使它们可变:

type DeepMutable<T> = { -readonly [P in keyof T]: DeepMutable<T[P]> }
type DataTableHeader = DeepMutable<ReadonlyDataTableHeader>;
Run Code Online (Sandbox Code Playgroud)

DeepMutable实用程序类将输入类型递归映射到新类型,删除任何readonly修饰符)

现在,如果你将 a 分配DataTableHeader[]:headersprop TS 会抱怨 aDeepMutable[]无法分配给 a DeepReadonly[],但由于我们已经知道类型匹配,所以我们可以告诉它闭嘴:

import type { VDataTable } from 'vuetify/components'

type ReadonlyHeaders = VDataTable['$props']['headers']

const headers: ReadonlyHeaders = [...]
Run Code Online (Sandbox Code Playgroud)

虚拟化3.3

直到 v3.3,VDataTable 仍处于实验室阶段,因此必须从vuetify/labs/components. 此外,Vuetify 没有导出类型,而仅导出构造函数:

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

type Headers = InstanceType<typeof VDataTable>['headers']
Run Code Online (Sandbox Code Playgroud)

(VDataTable是一个构造函数,所以我们将它转​​换为类型typeof,获取它构造的类型InstanceType,然后headers通过索引获取 prop)

数组类型不包括undefined,但可以是数组的数组。因此,展开项目类型略有不同:

type UnwrapReadonlyArrayType<A> = A extends Readonly<Array<infer I>> ? UnwrapReadonlyArrayType<I> : A
type ReadonlyDataTableHeader = UnwrapReadonlyArrayType<Headers>;
Run Code Online (Sandbox Code Playgroud)

UnwrapArrayType从数组类型中递归地提取项目类型,直到没有数组剩下,我们有了DataTableHeader

与 3.4 一样,这为您提供了只读类型,可以像上面那样解包。


直到 Vuetify 3.3

标头不是只读的,否则与上面相同:

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

type Headers = InstanceType<typeof VDataTable>['headers'] // gives `DataTableHeader[] | DataTableHeader[][]`
// optionally unwrap DataTableHeader
type UnwrapArrayType<A> = A extends Array<infer I> ? UnwrapArrayType<I> : A
type DataTableHeader = UnwrapArrayType<Headers>
Run Code Online (Sandbox Code Playgroud)

  • Vuetify 3.4 似乎不再适用:( (2认同)

小智 4

Vuetify 定义了 DataTableHeaders 类型lib/labs/components.d.ts,但不会导出以供外部使用。您可以通过复制此类型以在组件中使用来定义自己的类型。

type DataTableHeader = {
    key: string;
    value?: SelectItemKey;
    title: string;
    colspan?: number;
    rowspan?: number;
    fixed?: boolean;
    align?: 'start' | 'end';
    width?: number;
    minWidth?: string;
    maxWidth?: string;
    sortable?: boolean;
    sort?: DataTableCompareFunction;
};

const headers:DataTableHeader  = [
    { title: 'The title', key: 'the_key' },
  ]

Run Code Online (Sandbox Code Playgroud)