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

TypeScript中能否让子函数继承父函数泛型作为默认类型?

在TypeScript中让子函数继承父函数的类型参数作为默认值是否可行?

可行,但无法通过你当前的独立函数写法实现——独立函数之间无法自动共享类型上下文。需要调整函数设计,通过闭包、高阶函数或回调的方式传递父函数的类型参数,以下是几种实现方案:

方案一:将子函数作为父函数的内部辅助方法

把buildJoin封装在返回辅助工具的函数里,让它直接捕获父类型参数:

interface IParent {
    id: number;
    name: string;
}

interface IChild {
    id: number;
    name: string;
    ParentId: number;
}

// 改造为带类型绑定的查询构建器
function createQueryBuilder<T>() {
    // buildJoin自动使用外部的T类型作为父表类型
    function buildJoin<Child>(foreignKey: keyof Child, otherColumn: keyof T): string {
        return `JOIN f on t.${String(foreignKey)} = f.${String(otherColumn)}`;
    }

    return {
        buildJoin,
        select(query: { select: string; join: string }) {
            return `${query.select} ${query.join}`;
        }
    };
}

// 使用示例
const parentQuery = createQueryBuilder<IParent>();
parentQuery.select({
    select: 'select * from Parent',
    join: parentQuery.buildJoin<IChild>('ParentId', 'id') // 无需手动指定父类型
});

方案二:通过回调函数传递类型上下文

让select接收一个回调,回调内可直接使用父类型参数调用buildJoin:

interface IParent {
    id: number;
    name: string;
}

interface IChild {
    id: number;
    name: string;
    ParentId: number;
}

function buildJoin<Child, Parent>(foreignKey: keyof Child, otherColumn: keyof Parent): string {
    return `JOIN f on t.${String(foreignKey)} = f.${String(otherColumn)}`;
}

// 改造select,传入回调获取绑定了父类型的join构建器
function select<T>(getQuery: (buildJoin: <C>(fk: keyof C) => string) => { select: string; join: string }) {
    const boundBuildJoin = <C>(foreignKey: keyof C) => buildJoin<C, T>(foreignKey, 'id');
    const query = getQuery(boundBuildJoin);
    return `${query.select} ${query.join}`;
}

// 使用示例
select<IParent>(buildJoin => ({
    select: 'select * from Parent',
    join: buildJoin<IChild>('ParentId') // 只需指定子类型
}));

方案三:高阶函数绑定父类型

先创建绑定了父类型的buildJoin函数,再用于select调用:

interface IParent {
    id: number;
    name: string;
}

interface IChild {
    id: number;
    name: string;
    ParentId: number;
}

function select<T>(query: {
    select: string,
    join: string,
}) {
    return `${query.select} ${query.join}`;
}

// 高阶函数:传入父类型,返回绑定该类型的buildJoin
function createJoinBuilder<Parent>() {
    return function buildJoin<Child>(foreignKey: keyof Child, otherColumn: keyof Parent): string {
        return `JOIN f on t.${String(foreignKey)} = f.${String(otherColumn)}`;
    };
}

// 使用示例
const buildParentJoin = createJoinBuilder<IParent>();
select<IParent>({
    select: 'select * from Parent',
    join: buildParentJoin<IChild>('ParentId', 'id') // 无需重复指定父类型
});

核心原因

TypeScript的类型参数作用域仅限于当前函数,独立函数无法自动感知外部函数的类型参数。必须通过闭包捕获、高阶函数传递或回调注入的方式,将父函数的类型参数传递给子函数,才能实现你期望的自动继承效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:50:32