首页 > 解决方案 > Typescript 通过引用传递属性

问题描述

我有一个具有 4 个不同属性的 Typescript 类,如下所示:

class MyClass {
     private x: number;
     private y: number;
     private z: number;
     private w: number;
}

我想创建四个增加这些属性的函数:

   incrementX() { this.x++; }
   incrementY() { this.y++; )
   ...

但是,我不想++重复增量逻辑 ( ),我想将它放在一个函数中。如果 Typescript 有像 C# 这样的 ref 参数,我会这样做:

   incrementX() { this.increment(ref this.x); }
   increment(p: ref number) { p++; }

Typescript 不支持通过引用传递。实现这一点的非类型安全方法是:

   incrementX() { this.increment("x"); }
   increment(p: string) {
       const self = this as any;
       self[p]++;
   }

它不是类型安全的。我可以轻松调用increment('not-a-property')而不会从编译器中得到错误。我添加了运行时检查以确保 self[p] 确实是一个数字,但我仍然想要编译器可以捕获的东西。

有没有一种类型安全的方式来实现这一点?

注意:显然我的实际代码并没有增加数字,而是做了一些非常复杂的事情——不是在数字上,而是在另一个类类型上。

标签: typescriptpass-by-referencepass-by-name

解决方案


你可以使用keyofnumber extends也许?只允许传递数字类的键。

这里的游乐场

class MyClass {
  public a: number = 0;
  public b: number = 0;
  public c: string = "";

  public increment(
     key: {
      [K in keyof MyClass]-?: number extends MyClass[K] ? K : never
    }[keyof MyClass]
  ) {
    this[key]++;
  }
}

const test = new MyClass();

test.increment("a");
test.increment("b");
test.increment("c"); // fail
test.increment("d"); // fail

推荐阅读