type NonNever<T> = [T] extends [never] ? never : T;
type Keys<T> = { [K in keyof T]: T[K] extends never ? never : K }[keyof T];
type R = Keys<{ a: string; b: never }>; // 'a'
写了个按 key 过滤的映射类型,结果整个对象类型变成空,取任何字段都报 TS2339。把条件拆出来单独悬停,那一支的结果是 never。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,条件类型遇到 never 会触发分发,而 never 是空联合,分发之后没有任何成员参与计算,结果就落在 never 上。再接一层映射类型,键一个都不剩。
「条件类型 never」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改完隔一天再看一次,当场正常不代表能稳住。
测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
处理上按这个顺序:先把条件类型抽出来 悬停看中间结果;确认传进来的联合类型里有没有混进 never;用方括号包住两侧 关掉分发再试;需要保留 never 时单独加一层判断排除。
改完只确认一件事:映射类型不再为空 取字段能正常提示 悬停看到的是具体键名联合。
