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

带条件泛型的自定义类型在useState中触发TS错误的原因与解决

TypeScript泛型类型使用问题排查与解决

问题场景

定义了如下泛型类型:

export type MutationResponse<T = never> = {
    status: number;
    message: string | null;
} & (T extends never ? {} : { data: T });

当省略泛型参数直接使用时出现错误:

const [response, setResponse] = useState<MutationResponse>({ status: 0, message: "" });

错误信息

Object literal may only specify known properties, and 'status' does not exist in type '() => never'

补充说明

显式指定泛型参数时使用完全正常:

const [response, setResponse] = useState<MutationResponse<string>>({ status: 0, message: "", data: "" });

原因分析

直接写MutationResponse而不指定泛型参数时,TypeScript不会自动用默认值never实例化这个泛型类型,而是把它当成了泛型类型构造器本身(即需要传入泛型参数才能生成具体类型的“模板”)。而useState的泛型参数要求传入具体类型,不是模板,此时TypeScript会把未指定泛型的MutationResponse误解析成返回never的函数类型,自然会提示对象里的status属性不存在。

解决方法

方法1:显式指定默认泛型参数

直接传入默认的never来实例化类型:

const [response, setResponse] = useState<MutationResponse<never>>({ status: 0, message: "" });

方法2:创建无泛型的别名

给默认实例化的类型单独起一个别名,方便后续直接使用:

export type MutationResponse<T = never> = {
    status: number;
    message: string | null;
} & (T extends never ? {} : { data: T });
// 定义对应默认never情况的别名
export type EmptyMutationResponse = MutationResponse<never>;

使用时直接调用别名:

const [response, setResponse] = useState<EmptyMutationResponse>({ status: 0, message: "" });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:52:08