Я не уверен, почему вы хотите этого (и если вы действительно хотите 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
также работают таким образом, поэтому я предполагаю, что все в порядке.
Хорошо, надеюсь, это поможет;удачи!
Ссылка на код