TypeScript如何实现基于函数参数的条件返回类型自动推断?
问题原因
当你显式指定第一个泛型参数T时,TypeScript会默认使用第二个泛型参数S的默认值false,并不会自动从传入的opts参数中推断S的类型。这就导致你传入的single: true与S=false的类型约束冲突,从而抛出类型错误。
解决方案
这里提供两种可靠的解决方式:
方式一:调整泛型推断逻辑,让S从opts自动推断
移除S的默认值,同时处理默认参数的类型兼容性:
interface Options<S extends boolean> { limit?: number offset?: number single?: S } const fetchItems = async <T = unknown, S extends boolean>( collection: string, opts: Options<S> = { single: false } as Options<S> ): Promise<S extends true ? T : T[]> => { const { data } = await axios.get<{ data: any }>(`/items/${collection}`, { params: { limit: opts.limit, offset: opts.offset, single: opts.single, }, }) return data.data }
调用示例:
// 自动推断S为true,返回Promise<{id: number}> await fetchItems<{ id: number }>("pages", { single: true }) // 自动推断S为false,返回Promise<{id: number}[]> await fetchItems<{ id: number }>("pages")
方式二:使用函数重载(更直观的类型约束)
通过重载函数直接定义不同参数对应的返回类型,避免泛型推断冲突:
interface Options<S extends boolean> { limit?: number offset?: number single?: S } // 重载1:传入single: true时,返回单个T类型 async function fetchItems<T>(collection: string, opts: Options<true>): Promise<T> // 重载2:不传opts或传入single: false时,返回T数组 async function fetchItems<T>(collection: string, opts?: Options<false>): Promise<T[]> // 通用实现 async function fetchItems<T>( collection: string, opts: Options<boolean> = {} ): Promise<T | T[]> { const { data } = await axios.get<{ data: any }>(`/items/${collection}`, { params: { limit: opts.limit, offset: opts.offset, single: opts.single, }, }) return data.data }
调用示例:
// 返回Promise<{id: number}> await fetchItems<{ id: number }>("pages", { single: true }) // 返回Promise<{id: number}[]> await fetchItems<{ id: number }>("pages")
两种方式都能解决你的类型错误问题,其中函数重载的方式类型提示更清晰,适合需要明确区分返回类型的场景。
内容的提问来源于stack exchange,提问作者Mattia D.
相关产品推荐
相关产品推荐

