TypeScript接口中如何实现更严格的函数调用签名类型约束
实现方案
你可以通过条件类型自动推导返回函数的参数签名,无需拆分多个父接口,同时保留直接访问body类型的能力,完整实现代码如下:
interface RequestInterface { endpoint: string body: unknown } interface GetPosts extends RequestInterface { endpoint: '/posts' body: never } interface CreatePost extends RequestInterface { endpoint: '/posts' body: string } // 条件类型判断是否需要携带body参数 type FactoryReturn<R extends RequestInterface> = R['body'] extends never ? () => void : (body: R['body']) => void function Factory<R extends RequestInterface>(endpoint: R['endpoint']): FactoryReturn<R> { return ((body?: R['body']) => { console.log(`Hitting ${endpoint} with ${body}`) }) as FactoryReturn<R> } const myLibrary = { getPosts: Factory<GetPosts>('/posts'), createPosts: Factory<CreatePost>('/posts'), } // 类型校验完全符合预期 myLibrary.getPosts() // 校验通过 myLibrary.getPosts('something') // 类型错误 myLibrary.createPosts(999) // 类型错误 myLibrary.createPosts() // 类型错误 myLibrary.createPosts('hi') // 校验通过 // 保留直接访问body类型的能力 type GetPostBody = GetPosts['body'] // never type CreatePostBody = CreatePost['body'] // string
该方案的优势如下:
- 所有请求定义统一继承同一个父接口,无需二选一,维护成本更低
- 完全保留原有的
body类型直接访问能力,适配其他业务场景的类型使用需求 - 参数是否必填完全由接口定义的
body类型自动推导,逻辑内聚无额外冗余定义
内容的提问来源于stack exchange,提问作者shennan
相关产品推荐
相关产品推荐

