目录
Types have separate declarations of a private property in TS
类型在 TS 中具有单独的私有属性声明
要解决“类型具有私有属性的单独声明”错误,请private
从已在父类中声明的成员中删除可见性修饰符,并确保没有安装同一包的多个版本。
下面是错误如何发生的示例。
class Person { constructor(private name: string, private age: number) {} } // ⛔️ Class 'Developer' incorrectly extends base class 'Person'. // Types have separate declarations of a private property 'name'.ts(2415) class Developer extends Person { constructor(private name: string, private age: number) { super(name, age); } }
该类使用
privatePerson
可见性修饰符声明name
和属性
。age
Developer
扩展自的类还声明了属性和。 Person
name
age
要解决该错误,请private
从子类的属性中删除可见性修饰符。
class Person { constructor(private name: string, private age: number) {} } class Developer extends Person { // ✅ removed private modifiers constructor(name: string, age: number) { super(name, age); } }
当类属性具有private
可见性时,只能从声明属性的类中访问它们(Person
在示例中)。
使用protected
可见性代替
如果您需要访问 的子类的属性Person
,请使用protected
可见性声明它们。
class Person { // 👇️ protected (accessible from subclasses) constructor(protected name: string, protected age: number) {} } class Developer extends Person { constructor(name: string, age: number) { super(name, age); // 👇️ can access protected members console.log(this.name); console.log(this.age); } } const dev = new Developer('Bobby Hadz', 30);
受保护的
成员可以在声明它们的类及其子类中访问。
使用同一包的不同版本
如果我们使用同一包的不同版本,也会发生该错误。
如果同一个包有多个版本,则发出的代码可能多次包含同一个类。
如果错误未解决,请尝试删除您的node_modules
package
-lock.json文件,重新运行
npm install
并重新启动您的 IDE。
# 👇️ (Windows) delete node_modules and package-lock.json rd /s /q "node_modules" del package-lock.json del -f yarn.lock # 👇️ (macOS/Linux) delete node_modules and package-lock.json rm -rf node_modules rm -f package-lock.json rm -f yarn.lock # 👇️ clean npm cache npm cache clean --force npm install
如果错误仍然存在,请确保重新启动 IDE 和开发服务器。
属性在 TS 中的类型“X”中是私有的,但在类型“Y”中不是私有的
当类扩展另一个或实现接口时属性的可见性发生更改时,会出现错误“属性在类型‘X’中是私有的,但在类型‘Y’中不是”。
要解决该错误,请使用具有适合您的用例的自定义逻辑的 setter 和 getter。
以下是错误发生方式的 2 个示例。
class Person { constructor(private name: string, private age: number) {} } // ⛔️ Class 'Developer' incorrectly extends base class 'Person'. // Property 'name' is private in type 'Person' but not in type 'Developer'.ts(2415) class Developer extends Person { // 👇️ can't change visibility here constructor(public name: string, public age: number) { super(name, age); } } // ------------------------------------------------------------- interface Employee { salary: number; } // ⛔️ Class 'Tester' incorrectly implements interface 'Employee'. // Property 'salary' is private in type 'Tester' but not in type 'Employee'.ts(2420) class Tester implements Employee { // 👇️ can't change visibility here private salary = 0; }
在第一个示例中,该类Person
具有 aname
和age
私有属性。
Developer
扩展自的类尝试Person
更改属性的可见性并重新声明它们。在扩展类或实现接口时,我们不允许更改可见性。
去掉public
标识符解决错误
要解决错误,请删除修饰符public
。
class Person { constructor(private name: string, private age: number) {} } class Developer extends Person { constructor(name: string, age: number) { super(name, age); } }
使用protected
可见性代替
私有
成员只能在类内访问。
如果您想让这些属性在子类内部可访问,请将它们的可见性更改为
protected。
class Person { // 👇️ protected (accessible in subclasses) constructor(protected name: string, protected age: number) {} } class Developer extends Person { constructor(name: string, age: number) { super(name, age); } logProps() { console.log(this.name); console.log(this.age); } }
如果您需要从外部访问类属性,请将它们设置为
public。
另一个常见的错误原因
错误的另一个原因是
类实现接口并尝试将属性设置为私有可见性。
interface Employee { salary: number; } // ⛔️ Class 'Tester' incorrectly implements interface 'Employee'. // Property 'salary' is private in type 'Tester' but not in type 'Employee'.ts(2420) class Tester implements Employee { private salary = 0; }
接口不允许定义private
或protected
属性,因为它们只关心类型的结构和功能。
如果您需要声明一个不能重新分配的属性,请使用
readonly
修饰符。
interface Employee { salary: number; } class Tester implements Employee { // 👇️ is readonly readonly salary = 0; } const tester = new Tester(); console.log(tester.salary); // 👉️ 0 // ⛔️ cannot reassign a read-only property tester.salary = 100;
该salary
属性仍然可以从外部访问,但不能重新分配。
使用setter和getter来解决错误
或者,您可以使用 setter 和 getter。
interface Employee { salary: number; } class Tester implements Employee { // 👇️ private (only accessible in this class) private _salary = 0; // 👇️ accessible from outside get salary() { // 👉️ your implementation return this._salary; } // 👇️ protected (can access in subclass) protected set salary(num: number) { this._salary = num; } } const tester = new Tester(); console.log(tester.salary); // 👉️ 0
消费者仍然可以从外部访问该salary
属性,但您可以提供
getter 方法的实现。例如,如果您想禁止这样做,您可以抛出一条有用的错误消息。
该_salary
属性private
只能从班级内部访问。
settersalary
是protected
,因此可以在类及其子类内部访问它。
额外资源
您可以通过查看以下教程来了解有关相关主题的更多信息: