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

为何推断的泛型Zod String类型会被判定为可赋值给never?

泛型类型在映射类型中意外被移除的问题

我尝试创建一个映射类型NoNever,用于排除类型为never的属性。其中一个属性的类型来自泛型Zod类型参数的z.infer<Z>:

export type NoNever<T> = { [P in keyof T as T[P] extends never ? never : P]: T[P] }

class Test<Z extends z.ZodString> {
    foo(args: NoNever<{ key: never, value: z.infer<Z>, bar: string }>) {
        const { key, value, bar } = args; // 'key'和'value'缺失
    }
}

key被正确移除,bar被保留,但value也被移除了。z.infer<Z>本应始终是string或更窄的类型,为何会被判定为可赋值给never而被移除?

编辑补充1

将z.infer<Z>替换为Z[_output]后,TypeScript会回退到z.ZodString作为底层类型,悬浮查看_output时显示解析类型为:

ZodType<string, ZodStringDef, string>._output: string

编辑补充2

实际上,任何键映射操作都会移除推断的Zod类型:

export type FilterNothing<T> = { [P in keyof T as T[P] extends T[P] ? P : P]: T[P] }

class Test<Z extends z.ZodString> {
    foo(args: FilterNothing<{ key: number, value: z.infer<Z>, bar: Date }>) {
        const { key, value, bar } = args;
    }
}

编辑补充3

实际上这与Zod无关,而是泛型类型在键映射中都会被移除:

export type FilterNothing<T> = { [P in keyof T as T[P] extends T[P] ? P : P]: T[P] }

class Test<Z> {
    foo(args: FilterNothing<{ key: number, value: Z, bar: Date }>) {
        const { key, value, bar } = args;
    }
}

编辑补充4

在未找到相关问题或文档的情况下,我已在microsoft/TypeScript提交了bug报告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:42:07