Typescript 嵌套类型问题:寻求泛型API抽象更优雅的实现方案
你要的简化写法完全可以实现,核心只需要给第二层泛型K2加上类型约束即可。
问题根源
你原来必须写条件类型的原因是:泛型K2仅设置了默认值'LevelTwo',没有增加extends keyof T1[K1]的约束,TypeScript 无法判定K2一定是T1[K1]的合法索引,直接写T1[K1][K2]会抛出类型错误,因此你才需要用条件类型做兼容兜底。
优化后代码
import axios from "axios"; interface ExampleInterface { LevelOne: { LevelTwo: { keyOne: string; keyTwo: number; keyThree: boolean; } } } // 类的泛型定义不用改 class ExampleClassOne <T1, K1 extends keyof T1> { // 仅修改requestMethod的泛型约束,增加K2 extends keyof T1[K1] requestMethod<K2 extends keyof T1[K1] = 'LevelTwo'> (): Promise<T1[K1][K2]> { return new Promise (async (resolve, reject) => { try { const requestResponse = await axios({ url: `https://someurl.com/api/`, method: 'GET' }) resolve(requestResponse.data) } catch (err: any) { reject(err.response.status); } }) } } class ExampleClassTwo { methodObj = { levelOne: new ExampleClassOne<ExampleInterface, 'LevelOne'>() } }
涉及的核心TS特性说明
- 泛型约束:通过
extends关键字限定泛型参数的取值范围,这里限定K2必须是T1[K1]的键名,确保后续索引访问的合法性。 - 索引访问类型:即
T[K]语法,用于获取类型T上键K对应的类型,要求K必须是keyof T的子类型,否则语法不合法。
如果你的业务场景里不需要动态传入其他K2值,甚至可以直接去掉K2泛型,返回值直接写Promise<T1[K1]['LevelTwo']>,写法更简洁。
内容的提问来源于stack exchange,提问作者gdew
相关产品推荐
相关产品推荐

