TypeScript:如何转换Promise返回的API对象(Next.js 13 Fetch)
解决方案
1. 修正工具方法的查询与类型转换
当前getPost函数存在两个核心问题:一是查询语句未使用传入的slug参数,会返回所有文章而非目标单篇;二是Sanity返回的日期为字符串格式,需要转为Date类型,同时要确保返回结果与Post类型结构匹配。
修改后的工具方法:
export async function getPost(slug: string): Promise<Post> { // 通过slug过滤目标文章,仅返回单个结果 const postData = await SanityClient.fetch(` *[_type == "post" && slug.current == $slug][0] `, { slug }); // 将slug参数传入查询语句 if (!postData) { throw new Error(`未找到slug为"${slug}"的文章`); } // 手动转换类型,处理日期字段并确保嵌套结构匹配 return { ...postData, publish_date: new Date(postData.publish_date), banner_image: postData.banner_image, category: postData.category || [], author: postData.author || [], body: postData.body || [] } as Post; }
2. 修正页面中的调用逻辑
App Router 场景(Next.js 13+)
页面组件可直接声明为异步组件,在组件内部调用工具方法获取数据:
// app/post/[slug]/page.tsx async function PostPage() { const post = await getPost('test-post'); return ( <div> <h1>{post.title}</h1> <p>{post.headline}</p> {/* 渲染其他Post属性 */} </div> ); } export default PostPage;
Pages Router 场景
使用getStaticProps或getServerSideProps预获取数据:
// pages/post/[slug].tsx export async function getStaticProps({ params }: { params: { slug: string } }) { const post = await getPost(params.slug); return { props: { post } }; } function PostPage({ post }: { post: Post }) { return ( <div> <h1>{post.title}</h1> <p>{post.headline}</p> </div> ); } export default PostPage;
3. 增强类型安全(可选)
若要严格校验返回数据的结构,可创建类型守卫函数:
function isPost(data: unknown): data is Post { const post = data as Post; return ( typeof post.title === 'string' && typeof post.headline === 'string' && typeof post.slug === 'string' && post.publish_date instanceof Date && Array.isArray(post.category) && Array.isArray(post.author) && Array.isArray(post.body) ); } // 在getPost中使用类型守卫 export async function getPost(slug: string): Promise<Post> { const postData = await SanityClient.fetch(` *[_type == "post" && slug.current == $slug][0] `, { slug }); if (!isPost(postData)) { throw new Error('返回的文章数据结构不匹配'); } return postData; }
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

