TypeScript中类属性的命名规范

38
根据官方样式指南,您应该避免在私有属性和方法前加下划线。由于我来自Java背景,通常会使用this关键字:
export default class Device {
    private id: string;

    constructor(id: string) {
        this.id = id;
    }

    public get id(): string { // [ts] Duplicate identifier 'id'.
        return this.id;
    }

    public set id(value: string) { // [ts] Duplicate identifier 'id'.
        this.id = value;
    }
}

但TypeScript编译器报错:[ts] 重复的标识符'id'。

TypeScript构造函数中是否有参数命名的常规惯例或最佳实践?

使用TypeScript的getset属性会产生错误。

有没有一种方法可以遵循样式指南并同时使用TypeScript的get/set属性?


不幸的是,以最佳实践为中心的问题并不适合在Stack Overflow上提问,因为它们主要会产生基于个人观点的答案(“我喜欢用这种方式...”,“人们通常使用这种方式...”)。虽然您可能会在其他问题的答案中看到作者认为的“最佳实践”,但专门询问它们是不符合规定的。有关更多信息,请参见[帮助/主题]。您可能需要从问题中删除与主题无关的部分,而将重点放在技术问题上。 - Kyll
1
不,编译器没有抱怨。你的例子是有效的。 - Paleo
抱歉,我更新了我的问题,我漏掉了一些代码,这实际上导致了错误。 - lenny
2
你不能这样做,因为它们最终都会成为同一个JS对象上的属性。 - toskv
2
在您的情况下,您可以通过一个简单的公共实例变量id来替换您的get id() / set id(val)。这样更易于阅读和编写,并且性能更高。 - Paleo
显示剩余2条评论
3个回答

51

回答

如果你想要使用getset访问器,你必须在私有属性前加下划线。在其他情况下不要使用。我认为在访问器中使用下划线是一种特殊情况,虽然在编码指南中没有明确写出,但这并不意味着它是错误的。他们在官方文档中使用了它。

下划线的原因

首先,我想强调fieldproperty之间的区别。在像Java或C#这样的标准高级OOP语言中,字段是一个不应该对其他类可见的私有成员。如果你想要以封装为目的将其公开,请创建一个属性。

Java中,你可以这样做(称为Bean属性):

private int id;

public int getId() {
    return this.id;
}

public setId(int value) {
    this.id = value;
}

然后您可以通过调用这些方法来访问属性:

int i = device.getId();
device.setId(i);

//increment id by 1
device.setId(device.getId() + 1);

另一方面,C# 的设计使其更容易使用属性:

private int id;

public int Id {
    get {
        return this.id;
    }
    set {
        this.id = value;
    }
}

(value始终是赋值的值。)

您可以直接为这些属性分配值或获取属性值。

int i = device.Id;
device.Id = i;

//increment id by 1
device.Id++;

在纯JavaScript中,没有真正的字段,因为类成员始终是公共的;我们只是称之为属性。

TypeScript中,您可以定义“真正”的C#-样式属性(具有封装性)。您可以使用访问器来实现。

private _id: number;

public get id(): number {
    return this._id;
}

public set id(value: number) {
    this._id = value;
}

使用方法:

let i: number = device.id;
device.id = i;

//increment id by 1
device.id++;

这里必须使用下划线,原因有两个:

  1. 在 JavaScript 中,所有类成员都是公共的。因此,通过在私有属性前加下划线,我们表示该属性(字段)是私有的,应该仅通过其公共属性来访问。
  2. 如果您将私有属性和公共属性命名为相同的名称,则 JavaScript 解释器无法确定是访问私有还是公共属性。因此,您会得到您写的错误:[ts] 重复的标识符'id'。

1

对于属性访问器,您可以使用_

请参阅Microsoft的示例https://www.typescriptlang.org/docs/handbook/2/classes.html#getters--setters

const fullNameMaxLength = 10;

class Employee {
  private _fullName: string;

  get fullName(): string {
    return this._fullName;
  }

  set fullName(newName: string) {
    if (newName && newName.length > fullNameMaxLength) {
      throw new Error("fullName has a max length of " + fullNameMaxLength);
    }

    this._fullName = newName;
  }
}

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
  console.log(employee.fullName);
}

这里提到的 TS 手册已经过时了,如果您能编辑一下以避免混淆就太好了。 - Ayush Tiwari
完成 - 链接已更新。谢谢@AyushTiwari - Vitaliy Markitanov

0
如果问题严格来说是:
“有没有一种方法可以遵循[typeScript]样式指南并同时使用TypeScript的get/set属性?”
其中TypeScript样式指南说:
“避免在私有属性和方法前加下划线。”
那么您可以使用$(美元符号)代替_(下划线)来为私有字段添加前缀。这样,您既可以摆脱[ts]重复标识符'blablabla'错误,同时仍然尊重TypeScript样式指南。
此外,但这只是我的意见,.$组合比._组合更易读。

5
这是错误的。美元前缀通常用于表示可观测量。 - jirig
6
这些指南是针对 TypeScript 项目代码库的贡献者而制定的。这并不是 TypeScript 社区的规定性指南。 - chocolateboy
2
“美元前缀通常用于可观察对象” - 这是不正确的。对于可观察对象,通常使用美元后缀。但我同意,与下划线前缀相比,使用美元前缀没有意义。两者都是有害的,但下划线是较小的恶,因为它经常用于将属性标记为私有。这几乎是“标准”的做法。 - Ruslan Stelmachenko
$符号在RxJS中用于表示Observables。请不要这样做。 - Sunny Patel
2
关于 _ 有什么邪恶之处? - marcg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接