Next.js接口返回类型约束报错:T可实例化为任意无关类型
Next.js API 接口类型约束与类型推断问题修复
问题重现
在Next.js中编写API接口时,希望强制约束返回的JSON结构,同时让React组件能推断接口返回类型,但遇到TypeScript类型错误。最小复现代码如下:
interface TestApiResponse<T> { number: number body: T } const testHandler = async <T>(): Promise<TestApiResponse<T>> => { return { number: 12, body: { slug: 'my-slug', }, } } export default createEndpoint(handler)
报错信息:
TS2322: Type '{ slug: string; }' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to '{ slug: string; }'.
参考的createEndpoint函数:
export function createEndpoint<T>( handler: (req: NextApiRequest) => Promise<TestApiResponse<T>> ) { return async function (req: NextApiRequest, res: NextApiResponse) { try { const response = await handler(req) res.status(response.status).json(response.data) } catch (err) { console.error(err) } } }
报错原因
testHandler中声明的泛型T是任意类型,但返回的body是固定结构{ slug: string }。TypeScript会认为T可能被实例化为任何与该结构无关的类型,因此抛出类型不兼容的错误。
解决方案
方案1:接口返回结构固定(无需泛型)
如果这个API的body结构是固定的,直接指定TestApiResponse的泛型参数,去掉testHandler的泛型声明:
interface TestApiResponse<T> { number: number body: T } // 明确指定返回类型的泛型为固定结构 const testHandler = async (req: NextApiRequest): Promise<TestApiResponse<{ slug: string }>> => { return { number: 12, body: { slug: 'my-slug', }, } } export default createEndpoint(testHandler)
方案2:接口需要动态返回不同结构(保留泛型)
如果API需要根据请求参数返回不同结构的body,需要确保T的范围可控,并让返回的body符合T的类型:
interface TestApiResponse<T> { number: number body: T } // 限制T为包含slug字段的类型(或其他基础约束) const testHandler = async <T extends { slug: string }>(req: NextApiRequest): Promise<TestApiResponse<T>> => { // 根据请求参数动态生成符合T结构的body const body = { slug: 'my-slug' } as T return { number: 12, body, } } // 在创建端点时明确指定T的具体类型 export default createEndpoint<{ slug: string }>(testHandler)
额外注意
createEndpoint函数中使用了response.status和response.data,但你的TestApiResponse接口并没有这两个字段,建议同步调整接口结构,避免运行时错误:
interface TestApiResponse<T> { status: number // 添加status字段 number: number data: T // 把body改为data,和createEndpoint逻辑匹配 }
内容的提问来源于stack exchange,提问作者EmJee
相关产品推荐
相关产品推荐

