Машинопись: закрытый ключ в публичном объекте - PullRequest
0 голосов
/ 27 сентября 2019

Есть ли способ добавить закрытый ключ в открытый объект?

export class user {
    public details: {
        lastname: string,
        firstname: string,
        username: string
    }
}

Я бы хотел, чтобы имя пользователя нельзя было устанавливать вне метода в классе.Пример, что-то вроде этого:

export class user {
    public details: {
        lastname: string,
        firstname: string,
        private _username: string
    }

    public setUsername() {
        this.details._username = `${lastname} ${firstname}`;
    }
}

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Я не уверен, почему вы хотите этого (и если вы действительно хотите private -подобное поведение, а не просто readonly), но я бы предложил в таких случаях поместить ваши классы в модуль, гдеВы экспортируете только предназначенные для общественности типы.Примерно так:

namespace Library {
  export interface Details {
    lastname: string;
    firstname: string;
  }
  interface PrivateDetails extends Details {
    username: string;
  }
  class PrivateUser {
    details: PrivateDetails;
    constructor(lastname: string, firstname: string) {
      this.details = { lastname, firstname, username: "" };
      this.setUsername(); // I guess?
    }
    setUsername() {
      this.details.username = `${this.details.lastname} ${
        this.details.firstname
      }`;
    }
  }
  export type User = Omit<PrivateUser, "details"> & {
    details: Details;
  };
  export const User: new (
    ...args: ConstructorParameters<typeof PrivateUser>
  ) => User = PrivateUser;
}

Итак, внутри библиотеки есть класс PrivateUser и тип PrivateDetails, где свойство details PrivateUser равно PrivateDetails.Эти типы и значения не экспортируются.Мы экспортируем User класс * и Details тип, где свойство details User равно Details.(* Обратите внимание, что мы на самом деле экспортируем type и const, оба с именем User. type соответствует типу User экземпляра, а const - конструктор. A class определение делает это автоматически, но мы должны сделать это в две строки).

Хорошо, давайте использовать это:

import User = Library.User;
const u = new User("Turing", "Alan");
console.log(u.details.firstname); // Turing
console.log(u.details.lastname); // Alan
console.log(u.details.username); // error!
// Property 'username' does not exist on type 'Details'.
// of course, at runtime, it still outputs "Turing Alan", just like a private property does
u.details.lastname = "Alda";
u.setUsername(); // okay
console.log(u.details.username); // still compiler error, outputs "Alda Alan" at runtime

Это работает так, как я думаю, вы хотите.Внутри Library класс PrivateUser имеет полный доступ к свойству details.username.Но снаружи, открытый класс User не делает.Это означает, что вы получите ошибку компилятора, если попытаетесь ее использовать.Конечно, во время выполнения доступ будет успешным, но свойства private также работают таким образом, поэтому я предполагаю, что все в порядке.

Хорошо, надеюсь, это поможет;удачи!

Ссылка на код

0 голосов
/ 27 сентября 2019

Почему не просто

export class user {

    public lastname: string,
    public firstname: string,
    private _username: string

    public setUsername() {
        this._username = `${this.lastname} ${this.firstname}`;
    }
}
...