Prismic Next.js应用ContentRelationshipField类型错误求助
Prismic Next.js 类型错误解决:获取关联分类颜色
功能运行正常,但存在类型错误,提示:属性'data'不存在于类型'ContentRelationshipField<"category">'和'EmptyLinkField<"Document">'上,错误出现在代码行:
const categoryColor = article.data.categories[0]?.category.data.color;
问题原因
Prismic自动生成的类型中,ContentRelationshipField有两种状态:已填充的关联文档(包含data属性),或者空的EmptyLinkField(无data属性)。TypeScript无法确定article.data.categories[0]?.category的具体类型,直接访问data会触发类型校验错误。
解决方法
使用Prismic提供的prismicH.isFilled.contentRelationship类型守卫,先确认关联字段已填充,再安全访问data属性:
方式一:分步检查写法
const firstCategory = article.data.categories[0]; let categoryColor: string | undefined; // 先检查数组元素存在,再验证关联字段是否有效 if (firstCategory && prismicH.isFilled.contentRelationship(firstCategory.category)) { // 通过类型断言确认文档类型为CategoryDocument categoryColor = (firstCategory.category as CategoryDocument).data.color; } const backgroundColor = categoryColor || "#ffffff";
方式二:简洁链式写法
const categoryColor = prismicH.isFilled.contentRelationship(article.data.categories[0]?.category) ? (article.data.categories[0].category as CategoryDocument).data.color : undefined; const backgroundColor = categoryColor || "#ffffff";
修改后的完整组件代码
import React from "react"; import { PrismicLink, PrismicText } from "@prismicio/react"; import { PrismicNextImage } from "@prismicio/next"; import * as prismicH from "@prismicio/helpers"; import type { ArticleDocument, CategoryDocument } from "../../prismicio-types"; import { getExcerpt } from "../../lib/getExcerpt"; import { findFirstImage } from "../../lib/findFirstImage"; import { dateFormatter } from "../../lib/dateFormatter"; import { asapMedium } from "../../utils/font"; type ArticleProps = { article: ArticleDocument; }; const Article: React.FC<ArticleProps> = ({ article }) => { const featuredImage = (prismicH.isFilled.image(article.data.featuredImage) && article.data.featuredImage) || findFirstImage(article.data.slices); const date = prismicH.asDate( article.data.publishDate || article.first_publication_date ); const excerpt = getExcerpt(article.data.slices); // 修正后的分类颜色获取逻辑 const firstCategory = article.data.categories[0]; let categoryColor: string | undefined; if (firstCategory && prismicH.isFilled.contentRelationship(firstCategory.category)) { categoryColor = (firstCategory.category as CategoryDocument).data.color; } const backgroundColor = categoryColor || "#ffffff"; return ( <li className="relative grid grid-cols-1 items-start gap-6 md:gap-8"> <PrismicLink document={article} tabIndex={-1}> <div className="overlay-color z-10 md:block" key={article.id} style={{ backgroundColor }} ></div> <div className="bg-gray-100 aspect-h-3 aspect-w-4 relative"> {prismicH.isFilled.image(featuredImage) && ( <PrismicNextImage field={featuredImage} fill={true} width="0" height="0" sizes="100%" alt="" className="object-cover" /> )} </div> </PrismicLink> <div className={`${asapMedium.className} overlay-text absolut-center-x absolute bottom-10 z-10 grid w-full grid-cols-1 justify-center gap-3 px-3 text-center align-top text-2xl uppercase drop-shadow-sm md:col-span-2`} > <h2 className="text-white"> <PrismicLink document={article}> <PrismicText field={article.data.title} /> </PrismicLink> </h2> </div> </li> ); }; export default Article;
内容的提问来源于stack exchange,提问作者Rom-888
相关产品推荐
相关产品推荐

