Соглашение об именах для свойств класса в TypeScript

В соответствии с официальным руководством по стилю вы должны

Избегайте префикса частных свойств и методов с помощью подчеркивания.

Как я исхожу из фона 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?

ИЗМЕНИТЬ
Извините, я пропустил важную часть кода, которая фактически вызывает ошибку компилятора TS.
Использование свойства get и set TypeScript вызывает ошибку.

Итак, мой обновленный вопрос: есть ли способ следовать руководству по стилю, а также использовать свойства get/set из TypeScript?

Ответ 1

Ответ

Если вы хотите использовать аксессоры get и set, вы должны префикс частной собственности с помощью подчеркивания. Во всех остальных случаях его не использовать. Я бы сказал, что использование подчеркивания с accesors является особым случаем, и хотя оно явно не написано в Правилах кодирования, это не значит, что это неправильно. Они используют его в официальной документации .

Причина подчеркивания

Для начала я хотел бы подчеркнуть разницу между field и property. На стандартных языках OOP высокого уровня, таких как Java или С#, поле является частным членом, который не должен быть видимым для других классов. Если вы хотите разоблачить его с помощью инкапсуляции, вы должны создать свойство.

В 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);

С другой стороны, С# был спроектирован так, чтобы было намного проще использовать свойства:

private int id;

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

(значение всегда является назначенным значением.)

Вы можете напрямую присваивать значения этим свойствам или получать значения свойств.

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

//increment id by 1
i

В простом JavaScript нет реальных полей, потому что члены класса всегда открыты; мы просто называем их свойствами.

В TypeScript вы можете определить "истинные" свойства, подобные С# (с инкапсуляцией). Для этого вы используете Accessors.

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++;

У вас есть, чтобы использовать подчеркивание здесь по двум причинам:

  • В JavaScript все члены класса являются общедоступными. Поэтому, помещая знак подчеркивания перед частной собственностью, мы подписываем, что это свойство (поле) является закрытым и к нему должно быть доступно только публичное свойство.
  • Если вы указали как личное, так и общедоступное свойство с тем же именем, интерпретатор JavaScript не будет знать, следует ли обращаться к частному или публичному свойству. Таким образом, вы получаете сообщение об ошибке, которое вы пишете: [ts] Дублировать идентификатор "id".

Ответ 2

Если вопрос строго:

Есть ли способ следовать руководству по стилю [ typeScript], а также использовать get/set свойства TypeScript?

В руководстве по стилю TypeScript говорится:

Избегайте префикса частных свойств и методов с помощью подчеркивания.

Затем вы можете использовать знак $ (знак доллара) вместо _ (подчеркивание) для префикса ваших личных полей. Таким образом, вы оба избавляетесь от ошибки [ts] Duplicate identifier 'blablabla', соблюдая при этом руководство по стилю TypeScript.

Кроме того, но это только мое мнение, комбинация .$ более читаема, чем комбинация ._.

Ответ 3

Для доступа к свойствам вы используете _.

Посмотрите пример из Microsoft https://www.typescriptlang.org/docs/handbook/classes.html#accessors:

let passcode = "secret passcode";

class Employee {
private _fullName: string;

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

set fullName(newName: string) {
    if (passcode && passcode == "secret passcode") {
        this._fullName = newName;
    }
    else {
        console.log("Error: Unauthorized update of employee!");
    }
}
}
let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
console.log(employee.fullName);
}