【问题标题】:Type inference for overloaded function with enum params?使用枚举参数对重载函数进行类型推断?
【发布时间】:2017-11-05 00:19:16
【问题描述】:

是否可以使用带有枚举参数的重载函数执行类型推断?例如,假设我正在尝试创建一个返回类型取决于枚举值的工厂函数:

enum Colors {
  Red,
  Green
};

abstract class Box { };
class RedBox extends Box { };
class GreenBox extends Box { };

class BoxFactory {
  static createBox(color: Colors.Red): RedBox;
  static createBox(color: Colors): Box {
    switch (color) {
      case Colors.Red:
        return new RedBox();
      case Colors.Green:
        return new GreenBox();
    }
  } 
}

function makeMeABox(color: Colors) {
  // Argument of type 'Colors' is not assignable to parameter of type 'Colors.Red'
  return BoxFactory.createBox(color);
}

(playground)

如果我生成一个声明文件,一般的重载甚至不会出现。但是,如果我删除 static createBox(color: Colors.Red): RedBox; 的重载,一切都会好起来的。

【问题讨论】:

  • 即使在 Java 和 C++ 等静态类型语言中,返回类型也不会被视为函数签名的一部分

标签: typescript


【解决方案1】:

您只缺少一个签名:

class BoxFactory {
  static createBox(color: Colors.Red): RedBox;
  static createBox(color: Colors): Box; // <--- THIS ONE
  static createBox(color: Colors): Box {
    switch (color) {
      case Colors.Red:
        return new RedBox();
      case Colors.Green:
        return new GreenBox();
    }
  } 
}

然后:

let a = BoxFactory.createBox(Colors.Red); // type of a is RedBox
let b = BoxFactory.createBox(Colors.Green); // type of b is Box

(code in playground)

【讨论】:

  • 您的方法效果很好,谢谢!你能帮我理解为什么我们需要与函数签名相同的额外重载吗?如果重载,编译器不会解析主函数签名吗?
  • 实际实现的签名不是重载列表的一部分,这意味着在您的代码中只有一个签名(color = Colors.Red),我的代码为一般情况添加了第二个签名。只是在这种情况下,实现的签名与之匹配。
猜你喜欢
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 2019-05-19
  • 2021-08-05
相关资源
最近更新 更多