You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript联合类型报错:GetStaticPropsResult不存在props属性

TypeScript联合类型访问报错分析与优化方案

我有以下函数定义:

export async function getPageProps(
    slug: string,
    variables: {
        [key: string]: any;
    } = {},
    appendResourcesToPage: Array<AppendedResource> = [],
): Promise<GetStaticPropsResult<PageProps>> 
{ ... }

对应的接口与类型定义:

export interface PageProps {
    pageData: any;
    menus: {
        headerMenu: MenuItem[];
        footerMenu: MenuItem[];
        drawerMenu: MenuItem[];
        drawerFooterMenu: MenuItem[];
    };
    siteOptions: SiteOptions;
    globalSettings: GlobalSettingsQuery | null;
}

export type GetStaticPropsResult<Props> =
  | { props: Props; revalidate?: number | boolean }
  | { redirect: Redirect; revalidate?: number | boolean }
  | { notFound: true; revalidate?: number | boolean }

当尝试以下写法时出现TypeScript错误:

const commonSiteProps = await getPageProps('', {}, []) as GetStaticPropsResult<PageProps>;
const { siteOptions, globalSettings, menus } = commonSiteProps?.props || {};

报错信息:TS2339: Property props does not exist on type GetStaticPropsResult<PageProps>

即使添加类型断言,错误依然存在:

const { siteOptions, globalSettings, menus } = (commonSiteProps as GetStaticPropsResult<PageProps>)?.props || {};

目前已通过以下方式解决,但写法不够简洁,需明确报错原因及更优实现:

const commonSiteProps = await getPageProps('', {}, []);
let siteOptions, globalSettings, menus;
if (commonSiteProps && 'props' in commonSiteProps) {
    siteOptions = commonSiteProps?.props.siteOptions;
    globalSettings = commonSiteProps?.props.globalSettings;
    menus = commonSiteProps?.props.menus;
}
if (!siteOptions || !globalSettings || !menus) {
    throw new Error('Invalid page props.');
}

报错原因

GetStaticPropsResult<PageProps>是联合类型,包含三个分支:

  1. 带props属性的成功分支
  2. 带redirect属性的重定向分支
  3. 带notFound: true的404分支

TypeScript的类型系统会严格校验联合类型的属性访问:只有所有分支都存在的属性,才能直接访问。props仅存在于第一个分支,因此直接访问commonSiteProps.props会触发类型错误。

之前的类型断言无效,是因为断言的对象仍是整个联合类型,并未缩小到具体的带props分支,TypeScript依然无法确定当前值所属分支。


更优解决方案

方案1:类型守卫+解构赋值(简洁版)

利用in操作符做类型守卫,同时完成解构:

const commonSiteProps = await getPageProps('', {}, []);

if ('props' in commonSiteProps) {
    const { siteOptions, globalSettings, menus } = commonSiteProps.props;
    if (!siteOptions || !globalSettings || !menus) {
        throw new Error('Invalid page props.');
    }
    // 后续直接使用siteOptions、globalSettings、menus即可
} else {
    // 处理重定向或404场景,比如抛出错误或执行对应逻辑
    throw new Error('Failed to fetch valid page props');
}

方案2:类型断言到具体分支(适用于确定返回成功分支的场景)

如果能确定getPageProps在当前场景下一定返回带props的分支,可直接断言到该具体类型:

const commonSiteProps = await getPageProps('', {}, []) as { props: PageProps; revalidate?: number | boolean };
const { siteOptions, globalSettings, menus } = commonSiteProps.props;

if (!siteOptions || !globalSettings || !menus) {
    throw new Error('Invalid page props.');
}

注意:此方式跳过TypeScript类型检查,仅适合100%确定返回值类型的场景,否则可能引发运行时错误。

方案3:封装工具函数复用判断逻辑

若多处需要处理此类场景,可封装类型守卫工具函数:

function isGetStaticPropsSuccess<Props>(
    result: GetStaticPropsResult<Props>
): result is { props: Props; revalidate?: number | boolean } {
    return 'props' in result;
}

// 使用示例
const commonSiteProps = await getPageProps('', {}, []);

if (isGetStaticPropsSuccess(commonSiteProps)) {
    const { siteOptions, globalSettings, menus } = commonSiteProps.props;
    if (!siteOptions || !globalSettings || !menus) {
        throw new Error('Invalid page props.');
    }
} else {
    // 处理其他分支逻辑
    throw new Error('Failed to fetch valid page props');
}

内容的提问来源于stack exchange,提问作者JorgeeFG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:14:59