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

如何将类的类型筛选为仅接受无参数的函数?

如何在TypeScript中严格筛选无参数且返回void的函数属性?

这个问题的根源在于TypeScript的函数类型兼容性规则:() => void会匹配任何返回void(或兼容void)的函数,哪怕它带有参数——因为TypeScript允许你调用函数时忽略多余的参数,同时返回void的函数可以接受任何返回值(只要你不使用该返回值)。

要实现严格筛选无参数且返回void的函数,我们需要调整类型判断逻辑,确保函数的参数个数、类型和返回值完全匹配。这里有两种可行的方案:

方案1:双向extends实现严格类型匹配

通过让目标函数类型和类属性的函数类型互相赋值(即双向extends判断),只有当两者完全兼容时才保留该属性键:

class Nandar {
    stuff: string | null = null;
    doSomething(a: string, b: string): void {
        console.log(`${a},${b}`);
    }
    nothing(): void {
        console.log('nothing');
    }
}

// 修改后的Delegates类型,添加双向extends判断
type Delegates<Type, Fn> = keyof {
    [K in keyof Type
    as (Type[K] extends Fn ? (Fn extends Type[K] ? K : never) : never)]: K
};

// 测试:仅匹配doSomething
type StringDelegate = (a: string, b: string) => void;
type StringKeys = Delegates<Nandar, StringDelegate>; // "doSomething"

// 测试:仅匹配nothing
type NothingDelegate = () => void;
type NothingKeys = Delegates<Nandar, NothingDelegate>; // "nothing"

方案2:利用工具类型直接检查参数和返回值

如果你只针对无参数、返回void的场景,可以直接用Parameters和ReturnType工具类型明确判断:

type StrictVoidNoArgDelegates<Type> = keyof {
    [K in keyof Type
    as (Type[K] extends (...args: any[]) => void 
        ? Parameters<Type[K]> extends [] 
            ? K 
            : never 
        : never)]: K
};

// 测试:仅匹配nothing
type OnlyNothingKeys = StrictVoidNoArgDelegates<Nandar>; // "nothing"

为什么原代码不生效?

原代码中仅使用Fn extends Type[K]判断,对于() => void来说,(a: string, b: string) => void是符合这个条件的——因为TypeScript允许你把多参数函数赋值给少参数的函数类型(调用时忽略多余参数)。而双向extends判断会排除这种情况,因为() => void无法赋值给(a: string, b: string) => void(后者要求必须传入两个参数)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:45:28