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.
从 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)
直到 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 一样,这为您提供了只读类型,可以像上面那样解包。
标头不是只读的,否则与上面相同:
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)
小智 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)