⛔ 裸立、不分级 —— by the domain:engine execution PM seat。⛔ 无 domain:*、⛔ 无优先级、⛔ 无类型:三者都是分诊的写权。
本卡由 #17690 / PR #17876 交付中证伪一条卡面前提而另立,由该卡执行席裁定(选项 B)。⛔ 不在该 PR 内扩面。
一句话问题
TursoDriver.beginTransaction() 在 remote 模式下返回一个 libsql 事务,而它继承来的声明承诺的是 Promise<Knex.Transaction> —— any 掩盖的不是一道未收窄的门,是一个真实的 Liskov 违例。
测量(读数取于 origin/main 与 PR #17876 的 head 1c479a33fe)
| 读数 |
值 |
TursoDriver 的基类 |
export class TursoDriver extends SqlDriver(turso-driver.ts:536) |
| override 的约束声明(TS 按基类查,⛔ 不按接口) |
SqlDriver.beginTransaction(): Promise<Knex.Transaction>(sql-driver.ts:8752) |
| 契约声明 |
IDataDriver.beginTransaction(): Promise<unknown>(data-driver.ts:322) |
TursoDriver.beginTransaction 现在发布 |
Promise<any> |
| remote 分支实际返回 |
RemoteTransport.beginTransaction() → return this.client!.transaction() —— libsql 客户端事务 |
⇒ ⭐ 子类在一条路径上返回了基类声明不允许的类型。 any 是让编译器闭嘴的那个东西。
控制项:同一轮把 RemoteTransport.beginTransaction 从 Promise<any> 收窄到 Promise<unknown> 成功落地(它实现的是接口,不是 override)⇒ 该轮的收窄手法本身有效,这一格不同不是因为手法不灵,而是因为约束声明不同。
⛔ 为什么这不能用 #17690 的既定修复形状关掉
把 TursoDriver.beginTransaction 换成契约的 Promise<unknown> 不编译:TS2416,Promise<unknown> 不可赋给 Promise<Transaction<any, any[]>> —— unknown 比基类声明更宽。
⚠️ 而 #17690 卡面自身在这一格上自相矛盾:它的「Not findings」小节逐字点名保护了 SqlDriver.beginTransaction publishes Promise<Knex.Transaction> … 比声明更窄 —— the honest direction,同时又要求这个 override 换成契约类型。两者不能同时成立。
已被定价的两条出路(⛔ 本卡不预判,留给分诊/维护者)
| 选项 |
实测代价 |
A —— 把 SqlDriver.beginTransaction 放宽成 Promise<unknown>,再把两个 override 收窄到它 |
消费端站点从 11 涨到 25(+14),且反转一次诚实的收窄 —— 每个 driver-sql 消费者从此拿不到 knex 事务类型。⛔ 并与 #17690 的「Not findings」直接冲突 |
C —— 重构 remote 事务句柄,让 TursoDriver 真的答出基类的类型 |
运行时改动。⛔ 超出 #17690 的声明面,该轮按派发令「停下报告」而未尝试 |
⇒ 本卡承载的是这个选择,以及选定后的落地。⛔ 本席未替维护者选 A 或 C。
该门保持 Promise<any>,但已在代码里被点名:站点注释写明它是 LSP 违例、附 TS2416 收据与两条出路的定价。⛔ 未 re-mask、⛔ 未加 !、⛔ 未 cast。
Dedup 声明
⚠️ 本席的去重限于开着的 domain:engine 卡与本轮读到的邻居;#17876 的轮次另扫了 500 张最近更新的卡(#3739–#17876,开+关)。beginTransaction × LSP / TS2416 / Knex.Transaction 未命中既有卡。邻居非重复:#17690(本源,八门已修)· #17279 与 #16787(type-surface-only 谓词的同族限制,⛔ 不是本主题)。
Refs
#17690 / PR #17876(本源与证伪)· turso-driver.ts:536、sql-driver.ts:8752、data-driver.ts:322、remote-transport.ts 的 beginTransaction · #15280 · #15267 · #17277(既定修复形状的三个前例)
Filed by the domain:engine execution PM seat · R2 · session_01RuoNSXUbBoWHkNS4AknTrM · 读数复核于 origin/main 与 1c479a33fe · 2026-09-12。⛔ 不分级、不指派。
Generated by Claude Code
⛔ 裸立、不分级 —— by the
domain:engineexecution PM seat。⛔ 无domain:*、⛔ 无优先级、⛔ 无类型:三者都是分诊的写权。本卡由 #17690 / PR #17876 交付中证伪一条卡面前提而另立,由该卡执行席裁定(选项 B)。⛔ 不在该 PR 内扩面。
一句话问题
TursoDriver.beginTransaction()在 remote 模式下返回一个 libsql 事务,而它继承来的声明承诺的是Promise<Knex.Transaction>——any掩盖的不是一道未收窄的门,是一个真实的 Liskov 违例。测量(读数取于
origin/main与 PR #17876 的 head1c479a33fe)TursoDriver的基类export class TursoDriver extends SqlDriver(turso-driver.ts:536)SqlDriver.beginTransaction(): Promise<Knex.Transaction>(sql-driver.ts:8752)IDataDriver.beginTransaction(): Promise<unknown>(data-driver.ts:322)TursoDriver.beginTransaction现在发布Promise<any>RemoteTransport.beginTransaction()→return this.client!.transaction()—— libsql 客户端事务⇒ ⭐ 子类在一条路径上返回了基类声明不允许的类型。
any是让编译器闭嘴的那个东西。控制项:同一轮把
RemoteTransport.beginTransaction从Promise<any>收窄到Promise<unknown>成功落地(它实现的是接口,不是 override)⇒ 该轮的收窄手法本身有效,这一格不同不是因为手法不灵,而是因为约束声明不同。⛔ 为什么这不能用 #17690 的既定修复形状关掉
把
TursoDriver.beginTransaction换成契约的Promise<unknown>不编译:TS2416,Promise<unknown>不可赋给Promise<Transaction<any, any[]>>——unknown比基类声明更宽。SqlDriver.beginTransaction publishes Promise<Knex.Transaction> … 比声明更窄 —— the honest direction,同时又要求这个 override 换成契约类型。两者不能同时成立。已被定价的两条出路(⛔ 本卡不预判,留给分诊/维护者)
SqlDriver.beginTransaction放宽成Promise<unknown>,再把两个 override 收窄到它TursoDriver真的答出基类的类型⇒ 本卡承载的是这个选择,以及选定后的落地。⛔ 本席未替维护者选 A 或 C。
现状(#17876 落地后的样子)
该门保持
Promise<any>,但已在代码里被点名:站点注释写明它是 LSP 违例、附TS2416收据与两条出路的定价。⛔ 未 re-mask、⛔ 未加!、⛔ 未 cast。Dedup 声明
domain:engine卡与本轮读到的邻居;#17876 的轮次另扫了 500 张最近更新的卡(#3739–#17876,开+关)。beginTransaction× LSP /TS2416/Knex.Transaction未命中既有卡。邻居非重复:#17690(本源,八门已修)· #17279 与 #16787(type-surface-only谓词的同族限制,⛔ 不是本主题)。Refs
#17690 / PR #17876(本源与证伪)·
turso-driver.ts:536、sql-driver.ts:8752、data-driver.ts:322、remote-transport.ts的beginTransaction· #15280 · #15267 · #17277(既定修复形状的三个前例)Filed by the
domain:engineexecution PM seat · R2 ·session_01RuoNSXUbBoWHkNS4AknTrM· 读数复核于origin/main与1c479a33fe· 2026-09-12。⛔ 不分级、不指派。Generated by Claude Code