5.6.4 • Published 10 months ago

@cimom/vben-core-typings v5.6.4

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

@cimom/vben-core-typings

该包提供了 Vue Vben Admin 项目的核心类型定义,包括通用类型、应用类型、路由类型、菜单类型等。它是整个项目类型系统的基础,确保了代码的类型安全和开发体验。

安装

pnpm add @cimom/vben-core-typings

基本使用

导入基础类型

import type {
  Nullable,
  Recordable,
  DeepPartial,
  TimeoutHandle,
  AnyFunction,
} from '@cimom/vben-core-typings';

// 可为空类型
const userName: Nullable<string> = null;

// 字符串键对象
const params: Recordable<string> = {
  id: '1',
  name: 'admin',
};

// 深度可选类型
interface UserConfig {
  id: string;
  name: string;
  settings: {
    theme: string;
    language: string;
  };
}

const partialConfig: DeepPartial<UserConfig> = {
  name: 'admin',
  settings: {
    theme: 'dark',
  },
};

// 超时句柄类型
let timer: TimeoutHandle;

// 任意函数类型
const handler: AnyFunction = (a: number, b: number) => a + b;

使用应用类型

import type { BasicUserInfo, AppConfig } from '@cimom/vben-core-typings';

// 用户信息
const userInfo: BasicUserInfo = {
  userId: '1',
  username: 'admin',
  realName: '管理员',
  avatar: '/avatar.png',
  roles: ['admin'],
};

// 应用配置
const appConfig: AppConfig = {
  apiUrl: 'https://api.example.com',
  title: 'Vben Admin',
  logo: '/logo.png',
  theme: 'light',
};

使用菜单和路由类型

import type {
  MenuRecordRaw,
  RouteLocationWithMeta,
} from '@cimom/vben-core-typings';

// 菜单配置
const menus: MenuRecordRaw[] = [
  {
    path: '/dashboard',
    name: 'Dashboard',
    icon: 'dashboard',
    children: [
      {
        path: '/dashboard/analysis',
        name: 'Analysis',
        icon: 'chart',
      },
      {
        path: '/dashboard/workbench',
        name: 'Workbench',
        icon: 'desktop',
      },
    ],
  },
];

// 带元数据的路由
function handleRoute(route: RouteLocationWithMeta) {
  console.log(route.meta.title);
  console.log(route.meta.icon);
  console.log(route.meta.permissions);
}

包含类型

基础类型 (basic.d.ts)

提供基础通用类型:

// 基础选项类型
interface BasicOption {
  label: string;
  value: string;
}

// 选择器选项
type SelectOption = BasicOption;

// 标签选项
type TabOption = BasicOption;

// 基础用户信息
interface BasicUserInfo {
  // 头像
  avatar: string;
  // 用户昵称
  realName: string;
  // 用户角色
  roles?: string[];
  // 用户id
  userId: string;
  // 用户名
  username: string;
}

// 类名类型
type ClassType = Array<object | string> | object | string;

辅助类型 (helper.d.ts)

提供各种工具类型:

// 深度可选类型
type DeepPartial<T> = T extends object
  ? { [P in keyof T]?: DeepPartial<T[P]> }
  : T;

// 深度只读类型
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

// 异步函数类型
type AnyPromiseFunction<T extends any[] = any[], R = void> = (
  ...arg: T
) => PromiseLike<R>;

// 普通函数类型
type AnyNormalFunction<T extends any[] = any[], R = void> = (...arg: T) => R;

// 任意函数类型
type AnyFunction<T extends any[] = any[], R = void> =
  | AnyNormalFunction<T, R>
  | AnyPromiseFunction<T, R>;

// 可空类型
type Nullable<T> = null | T;

// 非空类型
type NonNullable<T> = T extends null | undefined ? never : T;

// 字符串键对象
type Recordable<T = any> = Record<string, T>;

// 只读字符串键对象
interface ReadonlyRecordable<T = any> {
  readonly [key: string]: T;
}

// 定时器句柄类型
type TimeoutHandle = ReturnType<typeof setTimeout>;
type IntervalHandle = ReturnType<typeof setInterval>;

// 合并类型
type Merge<O extends object, T extends object> = {
  [K in keyof O | keyof T]: K extends keyof T
    ? T[K]
    : K extends keyof O
      ? O[K]
      : never;
};

// 合并多个类型
type MergeAll<T extends object[]> = T extends [infer F, ...infer R]
  ? F extends object
    ? R extends object[]
      ? Merge<F, MergeAll<R>>
      : F
    : never
  : {};

应用类型 (app.d.ts)

提供应用相关类型:

// 应用环境配置
interface AppEnvConfig {
  // 接口前缀
  VITE_GLOB_API_URL: string;
  // 接口前缀
  VITE_GLOB_API_URL_PREFIX?: string;
  // 项目标题
  VITE_GLOB_APP_TITLE: string;
  // 项目简称
  VITE_GLOB_APP_SHORT_NAME: string;
  // 上传URL
  VITE_GLOB_UPLOAD_URL?: string;
}

// 应用配置
interface AppConfig {
  // 项目标题
  title: string;
  // API接口URL
  apiUrl: string;
  // 上传URL
  uploadUrl?: string;
  // API接口前缀
  urlPrefix?: string;
  // 项目简称
  shortName?: string;
}

// 多语言类型
type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja' | 'ko';

// 主题类型
type ThemeType = 'dark' | 'light';

菜单类型 (menu-record.ts)

提供菜单相关类型:

// 菜单项
interface MenuRecordRaw {
  // 菜单路径
  path: string;
  // 菜单名称
  name: string;
  // 菜单图标
  icon?: string;
  // 是否禁用
  disabled?: boolean;
  // 子菜单
  children?: MenuRecordRaw[];
  // 菜单排序
  orderNo?: number;
  // 路由元数据
  meta?: RouteMeta;
  // 是否隐藏
  hidden?: boolean;
  // 是否隐藏子菜单
  hideChildrenInMenu?: boolean;
  // 重定向路径
  redirect?: string;
}

路由类型 (vue-router.d.ts)

扩展 Vue Router 的类型:

// 路由元数据
interface RouteMeta {
  // 路由标题
  title: string;
  // 是否忽略权限
  ignoreAuth?: boolean;
  // 角色列表
  roles?: string[];
  // 是否缓存
  keepAlive?: boolean;
  // 图标
  icon?: string;
  // 是否固定标签
  affix?: boolean;
  // 路由路径
  path?: string;
  // 过渡名称
  transitionName?: string;
  // 是否隐藏路由
  hideBreadcrumb?: boolean;
  // 是否隐藏子路由
  hideChildrenInMenu?: boolean;
  // 是否单级菜单
  single?: boolean;
  // 当前活动菜单
  currentActiveMenu?: string;
  // 是否禁用
  disabled?: boolean;
  // 排序
  orderNo?: number;
  // 是否忽略缓存
  ignoreKeepAlive?: boolean;
  // 是否隐藏标签
  hideTab?: boolean;
  // 是否在菜单中隐藏
  hideMenu?: boolean;
  // 是否动态路由
  dynamicLevel?: number;
  // 真实路径
  realPath?: string;
  // 权限列表
  permissions?: string[];
}

// 带元数据的路由位置
interface RouteLocationWithMeta extends RouteLocationNormalized {
  meta: RouteMeta;
}

// 扩展路由记录
interface ExRouteRecordRaw extends Omit<RouteRecordRaw, 'meta' | 'children'> {
  meta: RouteMeta;
  children?: ExRouteRecordRaw[];
  props?: Recordable;
  fullPath?: string;
}

标签类型 (tabs.ts)

提供标签页相关类型:

// 标签页项
interface TabItem {
  key: string;
  label: string;
  path: string;
  closable?: boolean;
  disabled?: boolean;
}

高级用法

类型扩展

可以通过模块声明扩展现有类型:

// 扩展路由元数据
import '@cimom/vben-core-typings';

declare module '@cimom/vben-core-typings' {
  interface RouteMeta {
    // 添加自定义属性
    customField?: string;
    importance?: number;
  }
}

类型组合

利用工具类型组合创建复杂类型:

import type {
  DeepPartial,
  Recordable,
  Merge,
  MergeAll,
} from '@cimom/vben-core-typings';

// 基础配置
interface BaseConfig {
  apiUrl: string;
  timeout: number;
}

// 主题配置
interface ThemeConfig {
  theme: 'light' | 'dark';
  primaryColor: string;
}

// 合并配置
type AppConfig = Merge<BaseConfig, ThemeConfig>;

// 创建可选配置
type OptionalConfig = DeepPartial<AppConfig>;

// 创建多个配置合并
type FullConfig = MergeAll<
  [BaseConfig, ThemeConfig, { features: Recordable<boolean> }]
>;

类型守卫

结合类型定义创建类型守卫函数:

import type { BasicUserInfo, MenuRecordRaw } from '@cimom/vben-core-typings';

// 用户信息类型守卫
function isUserInfo(obj: any): obj is BasicUserInfo {
  return (
    obj &&
    typeof obj === 'object' &&
    'userId' in obj &&
    'username' in obj &&
    'avatar' in obj
  );
}

// 菜单项类型守卫
function isMenuItem(obj: any): obj is MenuRecordRaw {
  return (
    obj &&
    typeof obj === 'object' &&
    'path' in obj &&
    'name' in obj &&
    typeof obj.path === 'string' &&
    typeof obj.name === 'string'
  );
}

与其他包的关系

  • @cimom/vben-types: 基于此包构建,提供了更高级别的类型封装和组织。
  • @cimom/vben-core-shared: 使用此包的类型定义作为基础工具函数的参数和返回值类型。
  • @cimom/vben-core-ui-kit: 使用此包的类型定义构建 UI 组件的 Props 和事件类型。
  • @cimom/vben-effects-hooks: 使用此包的类型定义作为钩子函数的参数和返回值类型。

注意事项

  1. 该包是核心类型定义,被多个其他包依赖,修改时需谨慎。
  2. 扩展类型时应避免破坏现有类型的兼容性。
  3. 在使用泛型类型时,应提供适当的类型参数以获得更好的类型推断。

常见问题

类型不兼容

当遇到类型不兼容问题时,可以使用类型断言或类型转换:

import type { Recordable, DeepPartial } from '@cimom/vben-core-typings';

// 使用类型断言
const config = someValue as Recordable<string>;

// 使用类型转换函数
function toPartial<T>(obj: T): DeepPartial<T> {
  return obj as DeepPartial<T>;
}

扩展 Vue Router 类型

如果需要在项目中使用扩展的路由类型,可以创建类型声明文件:

// typings.d.ts
import '@cimom/vben-core-typings/vue-router';

这将确保 Vue Router 的类型被正确扩展。

自定义类型工具

如果需要基于现有类型创建自定义工具类型,可以这样做:

import type { DeepPartial, Recordable } from '@cimom/vben-core-typings';

// 创建只读版本的 DeepPartial
type ReadonlyDeepPartial<T> = {
  readonly [P in keyof DeepPartial<T>]: DeepPartial<T>[P];
};

// 创建字符串枚举对象
type StringEnum<T extends string> = Recordable<T>;