首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Typescript函数返回类型继电器

Typescript函数返回类型继电器
EN

Stack Overflow用户
提问于 2019-05-29 03:18:32
回答 1查看 91关注 0票数 0

我有一个实现访问者模式的简单类:

代码语言:javascript
复制
abstract class MyNode {};
class MyNodeA extends MyNode {};
class MyNodeB extends MyNode {};

abstract class NodeVisitor {
  abstract visitMyNodeA(node: MyNodeA): unknown;
  abstract visitMyNodeB(node: MyNodeB): unknown;

  public visit(node: MyNode) {
    if(node instanceof MyNodeA) {
      return this.visitMyNodeA(node);
    } else if(node instanceof MyNodeB) {
      return this.visitMyNodeB(node);
    } else {
      throw new Error('Unknown node type on visitor');
    }
  } 
}

稍后,当我实现NodeVisitor时,我希望在每个访问函数上都有自定义返回类型

代码语言:javascript
复制
class MyNodeVisitor extends NodeVisitor {
  visitMyNodeA(node: MyNodeA): number {
    return 1;
  }
  visitMyNodeB(node: MyNodeB): number {
    return this.visit(new MyNodeA()) + 1;
  }
}

但是这会产生一个错误,因为TypeScript编译器没有意识到在visit上使用MyNodeA类型的参数调用会重定向到visitMyNodeA函数,该函数现在会返回一个number

我该如何实施这样的解决方案呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-29 03:36:35

是的,编译器不能自己解决这个问题。您可以帮助它做到这一点,但代价是复杂性更高( visit()实现中的类型安全性更低)。我的建议是给visit()一个generic签名,它的返回类型是基于polymorphic this type of subclassesconditional type

代码语言:javascript
复制
abstract class MyNode {myNode = "myNode"}
class MyNodeA extends MyNode {a = "a"}
class MyNodeB extends MyNode {b = "b"}

abstract class NodeVisitor {
  abstract visitMyNodeA(node: MyNodeA): unknown;
  abstract visitMyNodeB(node: MyNodeB): unknown;

  // call signature    
  public visit<T extends MyNode>(
    node: T
  ): T extends MyNodeA ? ReturnType<this["visitMyNodeA"]> : 
     T extends MyNodeB ? ReturnType<this["visitMyNodeB"]> : 
    never;

  // implementation signature is wider
  public visit(node: MyNode): unknown {
    if (node instanceof MyNodeA) {
      return this.visitMyNodeA(node);
    } else if (node instanceof MyNodeB) {
      return this.visitMyNodeB(node);
    } else {
      throw new Error("Unknown node type on visitor");
    }
  }
}    
class MyNodeVisitor extends NodeVisitor {
  visitMyNodeA(node: MyNodeA): number {
    return 1;
  }
  visitMyNodeB(node: MyNodeB): number {
    return this.visit(new MyNodeA()) + 1;
  }
}

这行得通吗?其思想是,您将引导编译器完成这样的分析:如果您传递一个MyNodeAvisit()将返回this.visitMyNodeA(node)的结果,MyNodeB也是如此。

希望这能有所帮助;祝你好运!

Link to code

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56348769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档