TypeScript 高级类型推断与重载不兼容

q3aa0525  于 4个月前  发布在  TypeScript
关注(0)|答案(5)|浏览(35)

@ahejlsberg

TypeScript版本: typescript@3.7.0-dev.20190925
搜索词:
代码

interface Curried2<a, b, z> {
  (a: a, b: b): z;
  (a: a): (b: b) => z;
}
interface Curry {
  <a, b, z>(f: (a: a, b: b) => z): Curried2<a, b, z>;
}

declare const curry: Curry;

curry(<T extends 0, U extends 1>(n: T, m: U) => n + m)(1)(0);
curry(<T extends 0, U extends 1>(n: T, m: U) => n + m)(1, 0);

另外,以下操作也无法正常工作:

interface Curried2<a, b, z> {
  (a: a): (b: b) => z;
  (a: a, b: b): z;
}

当移除重载函数时,如下所示:

interface Curried2<a, b, z> {
  (a: a, b: b): z;
}

或者

interface Curried2<a, b, z> {
  (a: a): (b: b) => z;
}

这些操作可以正常工作。

预期行为:

正确推断类型参数,并且所有参数值都能被正确拒绝。

实际行为:

没有错误。

实验链接:
相关问题:

ovfsdjhp

ovfsdjhp1#

@ahejlsberg,你能评论一下吗?我对此并不是100%确定。

o75abkj4

o75abkj42#

这确实是已知的设计限制。来自 #30215 :
当函数调用中的参数表达式是泛型函数类型时,如果满足以下条件,则将该函数类型的类型参数传播到调用的结果类型上:

  • 被调用的函数是一个返回具有单个调用签名的函数类型的泛型函数,

...
我们可以将此标记为建议,以支持结果函数类型中的多个签名。这是可能的,但并不简单。

q5lcpyga

q5lcpyga3#

刚刚在尝试描述泛型可调用类的概念时遇到了这个问题:

class Foo<T> {
  constructor(readonly value: T) {}
}

function callable<P extends readonly any[], R>(Constructor: new (...params: P) => R): typeof Constructor & ((...params: P) => R) {
  return function (...params) {
    return new Constructor(...params);
  } as typeof Constructor & ((...params: P) => R);
}

const CallableFoo = callable(Foo);
// => (new (value: any) => Foo<any>) & ((value: any) => Foo<any>)
// Should be: (new <T>(value: T) => Foo<T>) & (<T>(value: T) => Foo<T>)

const foo1 = CallableFoo(42);
// => Foo<any>
// Should be: Foo<number>

const foo2 = new CallableFoo(42);
// => Foo<any>
// Should be: Foo<number>
w7t8yxp5

w7t8yxp54#

翻译结果为:@treybrisbane为什么不用以下方法?

$x^{1}a_{0}b_{1}x$

uujelgoq

uujelgoq5#

在我的案例中,我试图让类型既可以通过new示例化,也可以通过调用来实现。我相信我可以解决这个问题。我只是想留下一个评论,因为我发现高阶推断没有起作用,尽管我的两个重载函数在参数和结果方面是相同的。

相关问题