TypeScript中如何为对象类型传递泛型?函数泛型复用疑问
解决方案
你完全可以在对象的类型定义中使用泛型,不需要专门创建选项函数。核心是让getBook的泛型与options中对应键的类型关联起来,下面是具体的修正方案:
问题分析
你的代码里有两个小问题需要先修正:
options中book的值是数组,但Options<T>定义的是单个对象,所以需要把Options<T>调整为数组类型,或者修改options的结构。- 当前
options的类型Record<Types, Options<??>>无法直接关联getBook的泛型,因为每个Types成员对应的config类型可能不同。
方案1:让TypeScript自动推断类型
最简洁的方式是不手动指定options的类型,让TS自动推断,然后让getBook基于推断出的类型返回对应结果:
enum Types { book = 'book', } type Base = { config: unknown } type Options<T> = { title: string, config: T } // 让TS自动推断options的类型,无需手动指定Record const options = { // 明确标注该数组的元素类型为Options<string[]> book: [{title:'title', config: ['some data']}] as Options<string[]>[] } // getBook的泛型约束为Types的成员,返回对应类型的结果 const getBook = <T extends Types>(type: T) => { return options[type] } // 调用时自动推断返回类型为Options<string[]>[] const bookData = getBook(Types.book) // bookData[0].config 类型自动识别为string[]
方案2:显式定义泛型类型映射
如果需要更严格的类型约束,可以先定义每个Types成员对应的config类型,再用泛型映射到options的类型:
enum Types { book = 'book', } type Base = { config: unknown } type Options<T> = { title: string, config: T } // 定义每个Types成员对应的config类型 type TypeConfigMap = { [Types.book]: string[] } // 泛型类型:将TypeConfigMap映射为对应的Options数组 type OptionsMap<T> = { [K in keyof T]: Options<T[K]>[] } // 用OptionsMap约束options的类型 const options: OptionsMap<TypeConfigMap> = { book: [{title:'title', config: ['some data']}] } // getBook根据传入的type返回对应类型的结果 const getBook = <K extends Types>(type: K) => { return options[type] } const bookData = getBook(Types.book) // bookData[0].config 类型为string[]
方案3:通过泛型约束getBook的返回类型
如果你想让getBook接受泛型参数来指定返回的config类型,可以添加类型约束确保传入的type与泛型匹配:
enum Types { book = 'book', } type Base = { config: unknown } type Options<T> = { title: string, config: T } type TypeConfigMap = { [Types.book]: string[] } const options = { book: [{title:'title', config: ['some data']}] as Options<TypeConfigMap[Types.book]>[] } // 泛型Desired约束为Base,同时确保传入的type对应的config类型匹配Desired['config'] const getBook = <Desired extends Base>( type: keyof TypeConfigMap & { [K in keyof TypeConfigMap]: TypeConfigMap[K] extends Desired['config'] ? K : never }[keyof TypeConfigMap] ) => { return options[type] as Options<Desired['config']>[] } // 手动指定泛型调用 const bookData = getBook<{config: string[]}>(Types.book) // 或自动推断 const bookData2 = getBook(Types.book)
内容的提问来源于stack exchange,提问作者DevOverflow
相关产品推荐
相关产品推荐

