Typescript 通过引用传递 属性
Typescript pass property by reference
我有一个 Typescript class 具有 4 个不同的属性,如下所示:
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] 确实是一个数字,但我仍然想要编译器可以捕捉到的东西。
是否有类型安全的实现方法?
注意:显然我的实际代码不会增加数字,而是做了一些非常复杂的事情 - 不是数字而是另一种 class 类型。
您可以使用 keyof
和 number extends
吗?只允许传递 class 的键,它们是数字。
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
一个解决方案是用 keyof MyClass
.
输入 p
increment(p: keyof MyClass): void {
this[p]++;
}
但这行不通。因为您的数字字段是 private
,并且因为在 MyClass 的键中您具有函数 increment
本身。
一个解决方案是只提取数字字段:
type OnlyNumberKeys<O> = {
[K in keyof O]: O[K] extends number ? K : never;
}[keyof O];
然后在increment
函数中使用这个类型:
class MyClass {
x: number;
y: number;
z: number;
w: number;
increment(p: OnlyNumberKeys<MyClass>): void {
this[p]++;
}
}
现在 p
只接受 'x' | 'y' | 'z' | 'x'
。
请注意,我必须删除所有 private
关键字。不知道有没有解决办法
我有一个 Typescript class 具有 4 个不同的属性,如下所示:
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] 确实是一个数字,但我仍然想要编译器可以捕捉到的东西。
是否有类型安全的实现方法?
注意:显然我的实际代码不会增加数字,而是做了一些非常复杂的事情 - 不是数字而是另一种 class 类型。
您可以使用 keyof
和 number extends
吗?只允许传递 class 的键,它们是数字。
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
一个解决方案是用 keyof MyClass
.
increment(p: keyof MyClass): void {
this[p]++;
}
但这行不通。因为您的数字字段是 private
,并且因为在 MyClass 的键中您具有函数 increment
本身。
一个解决方案是只提取数字字段:
type OnlyNumberKeys<O> = {
[K in keyof O]: O[K] extends number ? K : never;
}[keyof O];
然后在increment
函数中使用这个类型:
class MyClass {
x: number;
y: number;
z: number;
w: number;
increment(p: OnlyNumberKeys<MyClass>): void {
this[p]++;
}
}
现在 p
只接受 'x' | 'y' | 'z' | 'x'
。
请注意,我必须删除所有 private
关键字。不知道有没有解决办法