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

为何TypeScript泛型在此场景下无法正确推断setSortableFields类型并自动补全?

为什么TypeScript无法在此场景下正确推断setSortableFields的类型?

先看代码示例:

export type TesteProps<
    SortableFields extends true | false
> = (
    {
        pending: boolean,
        sortedFields: object,
        sortableFields: SortableFields
    }
) & (
    SortableFields extends true ? {
        setSortedFields: object
    } : {
        setSortedFields?: never
    }
);

export function Teste<
    SortableFields extends true | false
>(
    props: TesteProps<SortableFields>
) {
    if (props.sortableFields) {
        // 此处TypeScript自动推断类型为 Object | undefined,而非预期的Object
        const setSortableFields = props.setSortedFields;
        console.log(setSortableFields);
    }
    return <>{JSON.stringify(props)}</>;
}

问题原因

TypeScript的控制流分析无法将运行时的props.sortableFields判断与泛型参数SortableFields的条件类型分支建立关联。

泛型参数SortableFields是在函数调用时确定的,函数内部的if (props.sortableFields)只是对具体属性值的判断,TypeScript不会据此反向推导泛型参数的具体类型——它没办法确定此时SortableFields必然是true,所以只能保留setSortedFields的联合类型object | undefined。

解决方法

有几种可行的方式让TypeScript正确推断类型:

  • 使用类型断言
    直接在赋值时明确断言类型:
if (props.sortableFields) {
    const setSortableFields = props.setSortedFields as object;
    console.log(setSortableFields);
}
  • 自定义类型守卫
    通过类型守卫函数告诉TypeScript,当props.sortableFields为true时,props的类型对应SortableFields=true的分支:
function isSortable<T extends true | false>(props: TesteProps<T>): props is TesteProps<true> {
    return props.sortableFields === true;
}

export function Teste<SortableFields extends true | false>(props: TesteProps<SortableFields>) {
    if (isSortable(props)) {
        const setSortableFields = props.setSortedFields; // 此时类型推断为object
        console.log(setSortableFields);
    }
    return <>{JSON.stringify(props)}</>;
}
  • 重构类型为可辨识联合
    把TesteProps改成可辨识联合类型,让TypeScript能通过sortableFields直接收窄整体类型:
export type TesteProps = 
    {
        pending: boolean,
        sortedFields: object,
        sortableFields: true,
        setSortedFields: object
    } | {
        pending: boolean,
        sortedFields: object,
        sortableFields: false,
        setSortedFields?: never
    };

export function Teste(props: TesteProps) {
    if (props.sortableFields) {
        const setSortableFields = props.setSortedFields; // 类型推断为object
        console.log(setSortableFields);
    }
    return <>{JSON.stringify(props)}</>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:33:29