【问题标题】:difference between number and generic parameter数字和通用参数之间的区别
【发布时间】:2020-12-30 16:47:38
【问题描述】:

我正在用 typescript 编写一个类,但不知道如何区分泛型和数字类型参数。代码示例

class Test<T> {
  remove(value: T): boolean;
  remove(index: number): boolean;
  remove(indexOrValue: T|number): boolean {
    if (typeof indexOrValue === "number") {
      /* What about new Test<number>() */
      const index = indexOrValue as number;
      this.items.splice(index, 1)
      return true;
    } else {
      const index = this.items.indexOf(indexOrValue as T)
      if (index > -1) this.items.splice(index, 1);
      return true;
    }
    return false;
  }
}

PS:我不知道这个问题,我在这里写而不是搜索

【问题讨论】:

  • 解决这个问题的唯一方法是对不同的操作使用两种不同的方法,例如remove(T)removeAt(number)。作为一个额外的好处,这使代码更具可读性,并且您不需要任何运行时决策。
  • 我知道这一点。但是我正在编写已经在许多其他类中使用的基类。那就是我必须实现相同的方法。
  • 如果你在类型 T 的类中有一个字段,那么你可以在参数类型之上检查它的类型。这是一个黑客,但它会工作。当然你无法区分调用者的意图。如果没有任何外部信息,就无法做到这一点,因为 T=number 的签名是等效的,因此无法区分。
  • 如果Tnumber,那么当有人调用这个函数时如何知道他们是要按值删除还是按索引删除?
  • @IngoBürk 即使那样,您也只能删除元素,而不能再按索引。

标签: typescript typescript-generics


【解决方案1】:

为了解决这个问题,而不是定义许多函数或构造函数(如一些编程语言,如c++),只需定义一个函数或构造函数并使用switch-caseif-else 来处理它。也许对于两种不同的类型,您想实现两个不同的功能,但它很容易管理,只需为每种用法创建两个功能,然后从switch-caseif-else 中的remove() 函数调用它们。

【讨论】:

  • 问题是如何区分泛型和数字类型,因为如果用户使用数字作为泛型类型,那么这两种情况对于编译器来说都是相同的,但对我来说却不是。看看我的例子。
【解决方案2】:

我建议也使用单独的方法路线,但如果您正在寻找具有确切要求的解决方案,我想我已经通过检查数组中项目的类型找到了您正在寻找的东西。

看一下代码:

class Test<T> {
    items: T[] = [];

    remove(value: T): boolean;
    remove(index: number): boolean;
    remove(indexOrValue: T|number): boolean {
        const length = this.items.length;
        if (length === 0) {
            return false;
        }
         
        const isArgumentNumber = typeof indexOrValue === "number";
        const isGenericTypeNumber = typeof this.items[0] === 'number';
        if (isArgumentNumber) {
            if (isGenericTypeNumber) {
                // TODO: When input and class both are number
            } else {
                // TODO: When input is number but class is not   
            }
        } else {
            // TODO: When input is not a number
        }
  }
}

【讨论】:

  • 但是如果我有genNumber.items.push(1); 并且我会做genNumber.remove(1); 那么它将删除错误的值。
  • @9me 这就是我认为你想要做的。我提供的是一种识别通用项目类型是否为数字的方法。你如何使用它,由你决定,代码仅用于演示目的。
  • 示例代码显示的是识别类型的方法,没有其他逻辑,因为问题与泛型类型的识别有关,与方法的功能无关。
  • 我正在寻找类似 java 类的东西。因为我知道在 java 中你可以用数字和Object 类型方法定义两种不同的方法。我想知道TS中是否也存在同样的事情
  • @9me 你可以使用我提供的代码。现在你想如何使用它取决于你。你可以根据你的实现来修改 if 条件。
猜你喜欢
  • 2013-01-04
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多