NewableFunction接口的用途是什么



TypeScript中一个鲜为人知的内置接口是VoidFunction,它应该表示任何不带参数并返回void的函数。一个更不为人所知的是NewableFunction,其听起来像,它应该表示任何"是"的函数;"可再生";或";可施工的";(可能使用类似(new (...) => ...)的构造签名,但当您尝试使用此接口时,会出现意外行为。

例如,请尝试使用参数。使用Parameters<VoidFunction>,您可以获得预期的[]:

// Makes sense
type VoidParams1 = Parameters<VoidFunction>;
//   ^? []

使用ConstructorParameters会产生错误,因为VoidFunction是不可构造的。然而,ParametersConstructorParameters都不接受NewableFunction:

//@ts-expect-error Is newable, not a regular function
type CtorParams1 = Parameters<NewableFunction>;
// What?
type CtorParams2 = ConstructorParameters<NewableFunction>;
// Error:                                ^^^^^^^^^^^^^^^
// Type 'NewableFunction' does not satisfy the constraint 'abstract new (...args: any) => any'.

这已经足够奇怪了,但当你把它用作代码类型时:

function newfn(f: NewableFunction) {}
// This line is OK
newfn(class {});
// Error on the following line
newfn(Date); // `new Date()`...?
//    ^^^^
// Argument of type 'DateConstructor' is not assignable to parameter of type 'NewableFunction'.
//   Types of property 'apply' are incompatible.
//     ...
//       Type 'new () => any' is not assignable to type '(this: any) => any'.

那么,如果我不能将NewableFunction用作可更新函数,它有什么意义呢?为什么像new (...args) => any这样的类型还没有内置呢?它很常见。问题ms/TS#44337似乎没有解决这些问题。。。

游乐场


它似乎只接受";严格可更新";函数-只能用new调用的函数?使用newfn(Date)会引发错误,但newfn(Float32Array)不会。但是,为什么要这样设计呢?为什么这有用?

哦,我不知道我怎么错过了这个,但在3.2版本的发行说明中,我们得到了strictBindCallApply,它部分由两个新接口CallableFunctionNewableFunction实现。VoidFunction与此无关。

function foo(a: number, b: string): string {
return a + b;
}
let a = foo.apply(undefined, [10]); // error: too few argumnts
let b = foo.apply(undefined, [10, 20]); // error: 2nd argument is a number
let c = foo.apply(undefined, [10, "hello", 30]); // error: too many arguments
let d = foo.apply(undefined, [10, "hello"]); // okay! returns a string

以下是他们对这些新接口的看法:

这是通过在lib.d.ts中引入两种新类型CallableFunctionNewableFunction来实现的。这些类型分别包含正则函数和构造函数的bindcallapply的专用泛型方法声明。声明使用通用的rest参数(参见#24897)以强类型的方式捕获和反映参数列表。在strictBindCallApply模式中,使用这些声明来代替Function类型提供的(非常宽松的)声明。

所以它们实际上并不是我们TypeScript的常规用户要使用的。。。

最新更新