为什么 `Array` 不是 `CallableFunction`?

考虑如下一段代码:

const a = Array(...Array(24));
const b = Array.apply(null, Array(24));

a 能被推导为 any[]b 却只能被推导为 any。我一开始以为是 TS 版本的问题,因为 TS 3.2 才开始支持 strictBindCallApply。但当我升级到 TS 3.2,b 的类型推导结果依然是 any

当我点进 Array.apply 方法的定义,我才发现它被解析到了 Functionapply 方法:

interface Function {
    /**
      * Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function.
      * @param thisArg The object to be used as the this object.
      * @param argArray A set of arguments to be passed to the function.
      */
    apply(this: Function, thisArg: any, argArray?: any): any;
}

而能被正确推导的 apply,会解析到 CallableFunctionapply 方法:

interface CallableFunction extends Function {
    /**
      * Calls the function with the specified object as the this value and the elements of specified array as the arguments.
      * @param thisArg The object to be used as the this object.
      * @param args An array of argument values to be passed to the function.
      */
    apply<T, R>(this: (this: T) => R, thisArg: T): R;
    apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
}

我好奇为什么 Array.apply 不会被解析到此,于是我将 Array 强转为 CallableFunction,发现它们竟然是不相容的,tsc 会提示:

The 'this' context of type 'CallableFunction' is not assignable to method's 'this' of type '(this: null, ...args: any[]) => {}'.
  Type 'CallableFunction' provides no match for the signature '(this: null, ...args: any[]): {}'.

那么,是什么理由导致它们不相容的呢?这样的行为背后有什么深意吗?


Preview:

Cancel