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
相关产品推荐
相关产品推荐

