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

如何让TypeScript条件类型不匹配any类型?

问题描述

使用TypeScript条件类型过滤对象中类型为{visible: boolean}的字段时,any类型的字段(如示例中的value1)被错误地包含在结果中,需要修改类型定义以排除这类字段。

原始代码:

export type Column = {
    value1: any;
    value2: string;
    value3: {
        visible: boolean
    },
    value4: {
        visible: boolean
    }
}

type VisibleFieldOnColumn<T> = {
    [K in keyof T as NonNullable<T[K]> extends { visible: boolean }
    ? K
    : never]: T[K];
};

type Test = VisibleFieldOnColumn<Column>;
// Test 会包含 value1: any,不符合预期

const v:Test = {
    value1:'',  // 需要移除该字段
    value3:{visible:false},
    value4:{visible:false}
}
解决方案

修改条件类型,在判断字段类型是否匹配{visible: boolean}的同时,排除any类型的字段。核心思路是利用TypeScript中unknown extends any为true、而unknown extends { visible: boolean }为false的特性,区分any和真正的目标类型。

简洁实现

type VisibleFieldOnColumn<T> = {
    [K in keyof T as 
        NonNullable<T[K]> extends { visible: boolean } 
        ? (unknown extends NonNullable<T[K]> ? never : K) 
        : never
    ]: T[K];
};

可读性更强的实现(带辅助类型)

// 辅助类型:判断目标类型是否为 any
type IsAny<T> = unknown extends T ? (T extends unknown ? true : false) : false;

type VisibleFieldOnColumn<T> = {
    [K in keyof T as 
        NonNullable<T[K]> extends { visible: boolean } 
        ? (IsAny<NonNullable<T[K]>> extends true ? never : K) 
        : never
    ]: T[K];
};
效果验证

修改后,Test类型将只包含value3和value4,value1被正确排除:

type Test = VisibleFieldOnColumn<Column>;
// Test = { value3: { visible: boolean }; value4: { visible: boolean } }

// 此时以下代码会报错,符合预期
const v:Test = {
    value1:'', // 类型错误:属性value1不在Test类型中
    value3:{visible:false},
    value4:{visible:false}
}
关键逻辑说明
  • TypeScript中any类型与任何类型的extends判断都会返回true,这是原始代码中value1被误匹配的核心原因。
  • 通过unknown extends NonNullable<T[K]>可以精准判断目标类型是否为any(仅any会让该表达式为true),如果是则返回never,从而排除对应字段。
  • 辅助类型IsAny封装了判断逻辑,让代码意图更清晰,便于后续维护。

内容的提问来源于stack exchange,提问作者Mr.Trieu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:00:11