You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript 中如何对泛型类 prototype 正确使用 typeof 获取方法类型?

问题根源

  • 你在定义_fwd方法时用的typeof PoolConnection.prototype取的是无泛型绑定的原型类型,它的泛型参数永远使用默认的DefaultValueType,不会跟随当前ConnectionPool实例的自定义TDefaultValue泛型变化,导致方法的泛型默认值被擦除,最终推导为any。
  • 原代码中PoolConnection的定义在ConnectionPool之后,类型引用时无法拿到完整的实例类型定义。

修正方案

调整类的定义顺序,同时将_fwd方法的类型关联到当前ConnectionPool泛型对应的PoolConnection实例类型即可,修改后的完整代码如下:

export type DefaultValueType = string | number | boolean | Date | bigint | null

type NotImportant = any
export const META = 'meta'
export type QueryResult<T> = T[] & { [META]: NotImportant[] }

// 先定义PoolConnection
class PoolConnection<TDefaultValue = DefaultValueType> {
    
    constructor(private readonly conn: NotImportant) {
    }

    query<TRecord = Record<string, TDefaultValue>>(query: NotImportant): Promise<QueryResult<TRecord>> {
        return Promise.resolve([] as any)
    }
}

class ConnectionPool<TDefaultValue = DefaultValueType> {

    constructor(private readonly pool: NotImportant) {
    }

    async getConnection() {
        return new PoolConnection<TDefaultValue>(await this.pool.getConnection())
    }

    // 修正后的_fwd类型:直接关联当前泛型对应的PoolConnection实例类型
    private _fwd<K extends keyof PoolConnection<TDefaultValue>>(method: K): PoolConnection<TDefaultValue>[K] {
        return (async (...args: any[]) => {
            const conn = await this.getConnection()
            try {
                return await (conn[method] as any)(...args)
            } finally {
                // 释放连接
            }
        }) as any
    }

    query = this._fwd('query')
}


async function test() {
    const pool = new ConnectionPool<string>('secret')

    // 现在类型正确:QueryResult<Record<string, string>>
    const result = await pool.query("select * from users")  

    const conn2 = new PoolConnection<boolean>('secret')
    // 类型正常:QueryResult<Record<string, boolean>>
    const result2 = await conn2.query("select * from profiles");

     const conn3 = new PoolConnection('secret')
    // 类型正常:QueryResult<Record<string, DefaultValueType>>
    const result3 = await conn3.query("select * from profiles");
}

修改后测试代码中的result类型会正确推导为QueryResult<Record<string, string>>,和PoolConnection直接实例化的类型表现完全一致。


内容的提问来源于stack exchange,提问作者mpen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:12:01