为什么“打字稿”会推断出这种类型?

时间:2016-05-20 19:00:12

标签: node.js generics typescript

我尝试使用 promisify 的打字版本,这是一种将带有节点回调的函数转换为本机promises的方法,以便在等待异步时使用它们。

其中一种类型签名如下:

function promisify<A1, A2, R1>(
nodeFunction: (
      arg1: A1, 
      arg2: A2, 
      callback: (err: any, r1: R1) => any
      ) => any, 
arg1 : A1, 
arg2 : A2): Promise<R1> 

这是一个节点函数,它接受两个参数并在回调上返回一个值,例如fs.readFile,请注意,由于readFile有多个调用签名,该函数会询问这些参数所以我们可以推断A1A2

明确的泛型工作,但编译器无法推断类型,编译器的消息是:

The type argument for type parameter 'A2' cannot be inferred from the usage.
Consider specifying the type arguments explicitly.
Type argument candidate '(err: ErrnoException, data: Buffer) => void' 
is not a valid type argument because it is not a supertype of candidate 'string'.

readfile签名:

readFile(filename: string, encoding: string, 
         callback: (err: NodeJS.ErrnoException, data: string) => void): void;

如果我们在函数调用上传递两个字符串,那么唯一的重载是接受第二个参数上的字符串:

promisify(fs.readFile, 'file.txt', 'utf8')

为什么编译器选择了接受对象的重载而不是第二个参数上的字符串?

由于arg2肯定是字符串('utf8'),编译器应该知道A2是字符串,然后只选择接受string作为第二个参数的重载

这些都是签名:

export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void;
export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void;
export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void;

0 个答案:

没有答案