You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Kysley搭配PostgreSQL:timestamp字段为何未在运行时反序列化为JS的Date类型?

Kysley搭配PostgreSQL:timestamp字段为何未在运行时反序列化为JS的Date类型?

嗨,这个问题我太懂了!咱们先搞清楚原因,再给你解决办法:

为什么会出现这种情况?

你遇到的核心问题是TypeScript类型和运行时数据是完全独立的两码事

  • 你定义的TS接口只是给编译器看的编译时约束,不会改变实际运行时的数据格式;
  • Kysley本身只负责SQL语句构建和TS类型映射,它不会自动帮你做运行时的类型转换;
  • 底层的pg库默认会把PostgreSQL的timestamp/timestamptz字段返回成字符串,而不是JS的Date对象——这才是你看到tsModified是字符串的根本原因。

怎么解决?有两种常用方案:

方案一:直接配置pg客户端的类型解析器

pg库允许我们自定义特定数据库类型的解析逻辑,我们可以在创建连接池的时候,指定把timestamp类型转成Date

import { Pool } from 'pg';
import { Kysley, PostgresDialect } from 'kysley';

// 创建pg连接池时添加类型解析规则
const pool = new Pool({
  // 填写你的数据库连接信息:host、port、database、user、password等
  types: {
    // PostgreSQL中,timestamp的oid是1114,带时区的timestamptz是1184
    parseOutput: (value, oid) => {
      if (oid === 1114 || oid === 1184) {
        // 把字符串转成Date对象,同时处理空值
        return value ? new Date(value) : null;
      }
      return value;
    },
  },
});

// 将配置好的连接池传给Kysley
const db = new Kysley<YourDatabaseInterface>({
  dialect: new PostgresDialect({ pool }),
});

这样配置后,pg库会自动把所有timestamp类型的字段转成Date,Kysley查询结果自然就符合你的TS接口定义了。

方案二:用Kysley自带的typeParsers配置

如果你更想在Kysley层面处理,也可以用它提供的类型解析器配置,针对性地转换字段类型:

import { Kysley, PostgresDialect, typeParser } from 'kysley';
import { Pool } from 'pg';

const db = new Kysley<YourDatabaseInterface>({
  dialect: new PostgresDialect({
    pool: new Pool({ /* 你的数据库连接配置 */ }),
  }),
  typeParsers: [
    // 处理timestamp类型
    typeParser(
      { dataType: 'timestamp' },
      (value) => value ? new Date(value) : null,
    ),
    // 处理带时区的timestamptz类型
    typeParser(
      { dataType: 'timestamptz' },
      (value) => value ? new Date(value) : null,
    ),
  ],
});

这种方式更贴合Kysley的使用逻辑,不需要直接操作pg的底层配置,同样能实现把字符串转成Date的效果。

小提醒

记得处理空值哦!如果字段可能为null,一定要先判断value是否存在,不然new Date(null)会生成一个无效的日期对象。

备注:内容来源于stack exchange,提问作者igorludi

火山引擎 最新活动