Skip to content

[finding][drivers] 两个驱动包的测试脚手架用 (driver as any).knex 触达一个 protected 成员 —— 为读一个成员抹掉整个 driver 的类型(实测 52 文件 / 107 行) #6521

Closed as not planned

Description

@os-zhuang

从 #6320(PR #6517)的实施中带出。观察类,不是今天会炸的缺陷:无用户可触达面,pnpm test 全绿,任何门禁都不报。按 PD #10 另立单记录,不在 #6320 的 PR 里顺手扫。

事实(实测于 origin/main)

SqlDriver.knex 声明为 protected(packages/drivers/driver-sql/src/sql-driver.ts:1876),所以类外的测试 fixture 确实需要一次强制转换才能拿到 knex 实例做建表/插数据。当前全仓统一用的写法是:

let knexInstance: any;
knexInstance = (driver as any).knex;

git grep -c "as any).knex" origin/main -- packages/drivers/ 逐包汇总(计的是命中行数,非命中次数):

包 文件数 命中行数
driver-sql 37 74
driver-sqlite-wasm 14 32
driver-turso 1 1
合计 52 107

其中 packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver.ts 是非测试代码里的一处,其余在测试里。

为什么记下来

  1. as any 在这里是过量的。要读的成员只有一个(knex),但 as any 把整个 driver 的类型一起抹掉 —— 同一个 knexInstance 变量随后也被声明成 any,于是它上面的 schema.createTable / .insert / .destroy 全部不受检查,createTable 的回调参数也只能写成 (t: any)。一次转换的代价被放大到整条 fixture 链。

  2. 它落在所有既有门禁的盲区里,这一点是实测的、不是推断的:

  3. 现成的替代写法就在仓里(fix(drivers): 聚合函数拒收带上 ADR-0112 信封,并把两类条件分开措辞 (#5907) #6204 体例):点名要读的那一个成员,而不是抹掉整个对象。

    import type { Knex } from 'knex';
    let knexInstance: Knex;
    knexInstance = (driver as unknown as { knex: Knex }).knex;

    PR refactor(driver-sql)!: distinct 的第三参收成裸 FilterCondition (#6320) #6517 已在它自己新增的两个测试文件上用了这个写法并验证通过(两包 typecheck 绿、967 + 257 测试通过、eslint 绿),knex 在两个包里都是直接依赖,所以 import type { Knex } 处处可用。⛔ 它没有顺手扫兄弟文件 —— 超出 drivers: distinct 的第三参在 memory 与 sql 上语义不同 —— 把 sql 那面的写法交给 memory,静默返回未过滤全集(运行期实测) #6320 的范围。

不代裁的处置线索

  • 这是测试脚手架的类型卫生,不是契约缺陷,严重度应由分诊定,不由本单预设;
  • 若要扫,扫的是一个机械替换(52 文件),但值不值得扫是个判断题:它买到的是 fixture 链上的类型检查,付出的是一次大面积改动与其后的合并冲突面;
  • 另一个方向是根本不扫,而是给 SqlDriver 一个测试用的具名读取口,让 fixture 不再需要任何转换 —— 但那是往驱动上加面,需要真实业务/测试拉力才划算,⛔ 本单不预判;
  • 第三条:sqlite-wasm-driver.ts 里那一处非测试出现值得单独看一眼,与测试里的那批不是同一回事。

关联:#6320 / PR #6517(出处)、#4918(有意排除测试代码的那条护栏,已 closed)、#6204(as unknown as 具名类型 的体例)。

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 8, 2026
  2. changed the title [-][finding][drivers] 两个驱动包的测试脚手架用 `(driver as any).knex` 触达一个 `protected` 成员 —— 为读一个成员抹掉整个 driver 的类型(实测 ~50 文件 / ~120 处)[/-] [+][finding][drivers] 两个驱动包的测试脚手架用 `(driver as any).knex` 触达一个 `protected` 成员 —— 为读一个成员抹掉整个 driver 的类型(实测 52 文件 / 107 行)[/+] on Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    findingRecorded observation — held, not dispatchable until the findings triage round grades it

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions