如何将Prop定义为生成的接口中对象数组的其中一项类型?
如何将Prop定义为生成的接口中对象数组的其中一项类型?
嘿,我来帮你搞定这个TypeScript类型提取的问题!首先先把你给出的Payload生成的接口补全成可运行的TypeScript结构(按Payload的常规结构补了Media接口和sections的数组定义):
export interface Media { id: number; url: string; // 其他Media相关字段可根据实际情况补充 } export interface Page { id: number; Title?: string | null; slug?: string | null; slugLock?: boolean | null; sections?: Array< | { Title: string; Subtitle: string; Image: number | Media; 'Button Text': string; 'Button Link': string; id?: string | null; blockName?: string | null; blockType: 'Hero'; } // 这里可以添加其他区块类型,比如 Text、Gallery 等 > | null; }
接下来分两种场景给你说怎么提取类型定义Prop:
场景1:需要sections数组里所有可能的项类型
如果你想让组件接收sections里任意一种区块类型,就可以这样提取:
// 先去掉sections的null可能性,再取数组的项类型(得到所有区块的联合类型) type PageSection = NonNullable<Page['sections']>[number]; // 把Prop定义成这个类型 interface MySectionComponentProps { section: PageSection; }
这样你的组件就能接收任何一种sections里的区块,TypeScript会帮你做联合类型的检查。
场景2:只需要特定类型的区块(比如Hero)
如果你的组件专门处理Hero区块,那可以精准提取这个类型:
// 从所有区块类型里过滤出blockType为'Hero'的那一种 type HeroSection = Extract<NonNullable<Page['sections']>[number], { blockType: 'Hero' }>; // 定义Prop为HeroSection类型 interface HeroComponentProps { hero: HeroSection; }
这样你的组件Prop就严格对应了生成接口里的Hero结构,不仅不用手动重复写类型,还能享受完整的类型提示和错误检查。
举个实际使用的例子,比如Hero组件:
const HeroComponent = ({ hero }: HeroComponentProps) => { return ( <div className="hero"> <h1>{hero.Title}</h1> <p>{hero.Subtitle}</p> {/* 这里需要判断Image是Media对象还是id,按实际业务处理 */} <img src={(hero.Image as Media).url} alt={hero.Title} /> <a href={hero['Button Link']}>{hero['Button Text']}</a> </div> ); };
备注:内容来源于stack exchange,提问作者Chris




