如果TypeScript中存在对象函数,则调用它

时间:2018-03-07 18:01:11

标签: javascript typescript

我正在Typescript中实施二进制搜索树类作为学习语言的练习,并且我尝试使用generics来实现它。

在到目前为止已经实现的I类算法中,我需要对我处理的任何对象进行两次逻辑运算:检查它们是否相等,以及检查一个比另一个大。 这在操作像number这样的原始类型时很容易,因为我可以使用运算符===>来比较对象,但是因为我想创建一个泛型类,所以事情开始在这里变得复杂。

为了实现这一目标,我想出了这个"解决方案",其中用户的对象需要定义两个方法:equalsgreaterThan。基于此,我为我的树节点创建了这段代码:

class TreeNode<T> {
  /* A node used in the tree. */
  data: T;
  left: TreeNode<T> | undefined;
  right: TreeNode<T> | undefined;

  constructor(data: T) {
    this.data = data;
    this.left = undefined;
    this.right = undefined;
  }

  equals(obj: TreeNode<T>): boolean {
    /* Checks whether an equals function exists in the object. If it doesnt,
    tries to use === operator to perform equality check instead. */

    if ('equals' in obj.data)
      return <boolean>this.data.equals(obj.data);
    else
      return this.data === obj.data;
  }

  greaterThan(obj: TreeNode<T>): boolean {
    /* Checks whether an greaterThan function exists in the object. If it doesnt,
    tries to use > operator to check if this.data is greater than obj.data */

    if ('greaterThan' in obj.data)
      return <boolean>this.data.greaterThan(obj.data);
    else
      return this.data > obj.data;
  }
}

如您所见,我的代码用于比较节点(TreeNode的函数equalsgreaterThan将由BinarySearchTree调用类,我没有包括在这里),并且在比较节点时,它将检查所提到的方法是否在用户的对象中定义,存储在data属性中。如果是,我会用它们进行比较。如果它们不是,我会假设对象是一个数字,而不是使用关系运算符。 对我的解决方案感到满意,我尝试编译代码,导致以下错误:

  

TS2339:财产&#39;等于&#39;在&#39; T&#39;。

类型中不存在      

TS2339:Property&#39; greaterThan&#39;在&#39; T&#39;。

类型中不存在

因此,即使我检查了方法是否存在,编译器仍然拒绝编译代码。我该如何解决?

1 个答案:

答案 0 :(得分:1)

您可以为T定义类型约束,并将两个成员设为可选:

class TreeNode<T extends { equals?(o: T): boolean; greaterThan?(o: T): boolean }> {
    /* A node used in the tree. */
    data: T;
    left: TreeNode<T> | undefined;
    right: TreeNode<T> | undefined;

    constructor(data: T) {
        this.data = data;
        this.left = undefined;
        this.right = undefined;
    }

    equals(obj: TreeNode<T>): boolean {
        /* Checks whether an equals function exists in the object. If it doesnt,
        tries to use === operator to perform equality check instead. */

        if (this.data.equals)
            return <boolean>this.data.equals(obj.data);
        else
            return this.data === obj.data;
    }

    greaterThan(obj: TreeNode<T>): boolean {
        /* Checks whether an greaterThan function exists in the object. If it doesnt,
        tries to use > operator to check if this.data is greater than obj.data */

        if (this.data.greaterThan)
            return <boolean>this.data.greaterThan(obj.data);
        else
            return this.data > obj.data;
    }
}