如何将类的类型缩小到仅接受任何参数的函数?



游乐场的例子

假设我有这样一个类:

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

我可以使用此类型提取类的属性,将密钥缩小到仅给定的函数签名:

type Delegates<Type, Fn> = keyof {
[K in keyof Type
as Fn extends Type[K] ? K : never]: K
};

例如:

type StringDelegate = (a: string, b: string) => void;
const delegate: Delegates<Nandar, StringDelegate>; // delegate's only possible value is 'doSomething'

如果我想缩小到Nandar.nothing的类型,但是,我有一个问题。

使用类似的代码:

type NothingDelegate = () => void;
const delegate: Delegates<Nandar, NothingDelegate>; // delegate's values can be 'doSomething' or 'nothing'

我不想要'doSomething';我什么都不要。基本上,Typescript使用() => void来引用任何函数,使用任何数量的参数和任何返回类型。这不是我想让Typescript做的:我想让它引用不带参数的函数,也不返回任何东西。

手册上说

一个空返回的回调类型表示"我不会看你的返回值,如果存在">

但我确实想看看返回值,并确保它是void。我还想确保函数没有参数。有相应的语法吗?

问题是,对于一个函数可赋值给另一个函数,它不一定需要相同的密度。如果一个函数的形参类型与另一个函数相匹配,唯一的区别是该函数接受的形参较少,那么它是可赋值的:

type UhOh = (() => void) extends ((a: string, b: string) => void) ? true : false;
//   ^? true

可以看到,不带参数的函数可以赋值给带两个参数的函数。要确保函数没有参数,您可以使用Parameters实用程序类型检查它是否没有参数:

type NoArgFns<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? Parameters<T[K]>["length"] extends 0 ? K : never : never
}[keyof T];
type T = NoArgFns<Nandar>;
//   ^? "nothing"

游乐场

相关内容

最新更新