Skip to content

TypeScript 支持

Lovrabet SDK 提供完整的 TypeScript 支持,包括类型定义、类型推断和编译时错误检测。

💡 前置条件开始之前,请确保已完成 SDK 配置。推荐使用 CLI 自动生成配置。

类型导入

TypeScript
import {
  createClient,
  registerModels,
  // 配置类型
  type ClientConfig,
  type ModelsConfig,
  type ModelConfig,
  type Environment,
  // 查询类型
  type ListParams,
  type ListResponse,
  type FilterParams,
  type WhereCondition,
  type FieldCondition,
  type ConditionOperator,
  // 排序类型
  type SortList,
  SortOrder,
  // 下拉选项类型
  type SelectOption,
  type SelectOptionsParams,
  // 模型类型
  type BaseModelMethods,
  type LovrabetClient,
} from "@lovrabet/sdk";

环境与基础类型

Environment

TypeScript
// 环境类型
type Environment = "online" | "daily";

SortOrder 枚举

TypeScript
// 排序方向
enum SortOrder {
  ASC = "asc",   // 升序
  DESC = "desc", // 降序
}

// 排序配置(数组格式)
type SortList = Record<string, SortOrder>[];

// 使用示例
const sortList: SortList = [
  { id: SortOrder.DESC },
  { name: SortOrder.ASC },
];

配置类型

ModelConfig

TypeScript
// 单个模型配置
interface ModelConfig {
  /** 数据表名称(必填) */
  tableName: string;
  /** 数据集代码(必填,唯一标识) */
  datasetCode: string;
  /** 显示名称(可选,用于 UI 展示) */
  name?: string;
  /** 别名(可选,用于 client.models.alias 访问) */
  alias?: string;
  /** 数据库名称(可选,用于区分不同数据库中的同名表) */
  dbName?: string;
}

ModelsConfig

TypeScript
// 模型配置集合
interface ModelsConfig {
  /** 应用代码 */
  appCode: string;
  /**
   * 模型配置(支持两种格式)
   * - 数组格式(推荐)
   * - 对象格式(向下兼容)
   */
  models: ModelConfig[] | Record<string, ModelConfig>;
}

// 数组格式(推荐)
const config: ModelsConfig = {
  appCode: "my-app",
  models: [
    { datasetCode: "xxx", tableName: "users", alias: "users" },
    { datasetCode: "yyy", tableName: "orders", alias: "orders" },
  ],
};

// 对象格式(向下兼容,key 作为默认 alias)
const legacyConfig: ModelsConfig = {
  appCode: "my-app",
  models: {
    Users: { datasetCode: "xxx", tableName: "users" },
    Orders: { datasetCode: "yyy", tableName: "orders" },
  },
};

ClientConfig

TypeScript
interface ClientConfig {
  /** 应用代码 */
  appCode?: string;
  /** 自定义服务器 URL */
  serverUrl?: string;
  /** 运行环境,默认 'online' */
  env?: Environment;

  // === 认证配置 ===
  /** 用户 Token(Bearer 认证) */
  token?: string;
  /** 与 token 配对的时间戳(OpenAPI 模式必需) */
  timestamp?: number;
  /** API 访问密钥(签名认证) */
  accessKey?: string;
  /** API 密钥(签名认证) */
  secretKey?: string;
  /** 是否需要认证,默认 true */
  requiresAuth?: boolean;

  // === 模型配置 ===
  /** 直接传入模型配置 */
  models?: ModelConfig[] | Record<string, ModelConfig>;
  /** 引用已注册的配置名称 */
  apiConfigName?: string;

  // === 其他选项 ===
  options?: {
    /** 请求超时时间(毫秒) */
    timeout?: number;
    /** 重试次数 */
    retryCount?: number;
    /** 错误处理回调 */
    onError?: (error: any) => void;
    /** 需要重新登录时的回调 */
    onRedirectToLogin?: () => void;
    /** 启用调试日志(打印请求详情) */
    debug?: boolean;
  };
}

查询类型

ListParams

TypeScript
// 列表查询参数
interface ListParams {
  /** 当前页码,从 1 开始 */
  currentPage?: number;
  /** 每页数量 */
  pageSize?: number;
  /** 其他查询参数 */
  [key: string]: any;
}

ListResponse

TypeScript
// 列表响应
interface ListResponse<T> {
  /** 数据列表 */
  tableData: T[];
  /** 总数量 */
  total: number;
  /** 当前页码 */
  currentPage: number;
  /** 每页数量 */
  pageSize: number;
}

ConditionOperator

TypeScript
// 条件操作符
type ConditionOperator =
  | "$eq"       // 等于
  | "$ne"       // 不等于
  | "$gte"      // 大于等于
  | "$gteq"     // 大于等于(别名)
  | "$lte"      // 小于等于
  | "$lteq"     // 小于等于(别名)
  | "$in"       // 在集合内
  | "$contain"  // 包含(模糊匹配)
  | "$startWith" // 以...开头
  | "$endWith"; // 以...结尾

FieldCondition 与 WhereCondition

TypeScript
// 字段条件
type FieldCondition = {
  [K in ConditionOperator]?: any;
};

// Where 条件(支持嵌套)
type WhereCondition = {
  $and?: WhereCondition[];
  $or?: WhereCondition[];
  [field: string]: FieldCondition | WhereCondition[] | any;
};

// 使用示例
const where: WhereCondition = {
  $and: [
    { age: { $gte: 18, $lte: 45 } },
    { country: { $in: ["中国", "美国"] } },
    { name: { $contain: "张" } },
  ],
};

FilterParams

TypeScript
// Filter 方法参数(推荐使用)
interface FilterParams {
  /** Where 条件 */
  where?: WhereCondition;
  /** 选择返回的字段 */
  select?: string[];
  /** 排序规则 */
  orderBy?: SortList;
  /** 当前页码 */
  currentPage?: number;
  /** 每页数量 */
  pageSize?: number;
}

// 使用示例
const params: FilterParams = {
  where: {
    $and: [
      { status: { $eq: "active" } },
      { age: { $gte: 18 } },
    ],
  },
  select: ["id", "name", "email"],
  orderBy: [{ createdAt: SortOrder.DESC }],
  currentPage: 1,
  pageSize: 20,
};

下拉选项类型

SelectOption 与 SelectOptionsParams

TypeScript
// 下拉选项
interface SelectOption {
  label: string;
  value: string;
}

// 获取下拉选项的参数
interface SelectOptionsParams {
  /** 用作 value 的字段名 */
  code: string;
  /** 用作 label 的字段名 */
  label: string;
}

// 使用示例
const options = await client.models.users.getSelectOptions({
  code: "user_id",
  label: "user_name",
});
// 返回: [{ label: "张三", value: "001" }, { label: "李四", value: "002" }]

模型方法类型

BaseModelMethods

TypeScript
interface BaseModelMethods {
  /** 获取列表(基础查询) */
  getList<T = any>(params?: ListParams, sortList?: SortList): Promise<ListResponse<T>>;

  /** 高级过滤查询(推荐) */
  filter<T = any>(params?: FilterParams): Promise<ListResponse<T>>;

  /** 获取单条数据 */
  getOne<T = any>(id: string | number): Promise<T>;

  /** 创建数据 */
  create<T = any>(data: Record<string, any>): Promise<T>;

  /** 更新数据 */
  update<T = any>(id: string | number, data: Record<string, any>): Promise<T>;

  /** 删除数据 */
  delete(id: string | number): Promise<void>;

  /** 获取下拉选项 */
  getSelectOptions(params: SelectOptionsParams): Promise<SelectOption[]>;

  /** 导出 Excel */
  excelExport<T = string>(params?: ListParams): Promise<T>;
}

业务数据类型定义

定义数据模型

TypeScript
// 用户数据类型
interface User {
  id: string;
  name: string;
  email: string;
  status: "active" | "inactive";
  createdAt: string;
  updatedAt: string;
}

// 创建时的数据类型(排除自动生成字段)
type CreateUserData = Omit<User, "id" | "createdAt" | "updatedAt">;

// 更新时的数据类型(所有字段可选)
type UpdateUserData = Partial<Omit<User, "id" | "createdAt" | "updatedAt">>;

类型安全的 API 调用

TypeScript
const client = createClient();

// 带类型的查询
const result = await client.models.users.filter<User>({
  where: { status: { $eq: "active" } },
  pageSize: 20,
});
// result.tableData 类型为 User[]

// 带类型的单条查询
const user = await client.models.users.getOne<User>("123");
// user 类型为 User

// 带类型的创建
const newUser = await client.models.users.create<User>({
  name: "张三",
  email: "zhangsan@example.com",
  status: "active",
});

封装类型安全的 API

通用模型操作类

TypeScript
class TypedModel<T, CreateT = Partial<T>, UpdateT = Partial<T>> {
  constructor(
    private modelName: string,
    private client: LovrabetClient
  ) {}

  async filter(params?: FilterParams): Promise<ListResponse<T>> {
    return await this.client.models[this.modelName].filter<T>(params);
  }

  async getOne(id: string): Promise<T> {
    return await this.client.models[this.modelName].getOne<T>(id);
  }

  async create(data: CreateT): Promise<T> {
    return await this.client.models[this.modelName].create<T>(data);
  }

  async update(id: string, data: UpdateT): Promise<T> {
    return await this.client.models[this.modelName].update<T>(id, data);
  }

  async delete(id: string): Promise<void> {
    return await this.client.models[this.modelName].delete(id);
  }
}

// 使用
const userModel = new TypedModel<User, CreateUserData, UpdateUserData>(
  "users",
  client
);

const users = await userModel.filter({ pageSize: 10 });
const user = await userModel.create({
  name: "李四",
  email: "lisi@example.com",
  status: "active",
});

React Hook 封装

TypeScript
import { useState, useEffect, useCallback } from "react";

interface UseModelResult<T> {
  data: T[] | null;
  loading: boolean;
  error: string | null;
  refetch: (params?: FilterParams) => Promise<void>;
}

function useModel<T>(
  modelName: string,
  initialParams?: FilterParams
): UseModelResult<T> {
  const [data, setData] = useState<T[] | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const refetch = useCallback(async (params?: FilterParams) => {
    setLoading(true);
    setError(null);
    try {
      const response = await client.models[modelName].filter<T>({
        ...initialParams,
        ...params,
      });
      setData(response.tableData);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Unknown error");
    } finally {
      setLoading(false);
    }
  }, [modelName, initialParams]);

  useEffect(() => {
    refetch();
  }, [refetch]);

  return { data, loading, error, refetch };
}

// 使用
const { data: users, loading, error } = useModel<User>("users", {
  where: { status: { $eq: "active" } },
});

常见问题

Q: 如何为自定义字段添加类型?

TypeScript
interface UserWithCustomFields extends User {
  customField: string;
  metadata: Record<string, any>;
}

const users = await client.models.users.filter<UserWithCustomFields>();

Q: 如何处理动态模型名称?

TypeScript
type ModelNames = "users" | "orders" | "products";

const getModelData = async <T>(modelName: ModelNames): Promise<ListResponse<T>> => {
  return await client.models[modelName].filter<T>();
};

Q: 如何定义查询参数类型?

TypeScript
// 根据数据类型自动生成查询参数
type QueryParams<T> = {
  [K in keyof T]?: T[K] | FieldCondition;
} & FilterParams;

type UserQueryParams = QueryParams<User>;

const searchUsers = async (params: UserQueryParams) => {
  return await client.models.users.filter<User>(params);
};

下一步

  • Filter API 详解 - 复杂查询语法
  • 高级功能 - 多项目支持
  • 实际应用示例 - React/Vue 集成

基于飞书知识库同步生成,内容以飞书源文档为准