【问题标题】:Why private/protected members must originate from the same class for type compatibility?为什么私有/受保护成员必须来自同一个类以实现类型兼容性?
【发布时间】:2017-08-27 02:07:10
【问题描述】:

TypeScript Handbook 中,它说:

类中的私有成员和受保护成员会影响它们的兼容性。 当检查一个类的实例的兼容性时,如果 实例包含一个私有成员,那么目标类型也必须 包含源自同一类的私有成员。 同样,这同样适用于具有受保护成员的实例。 这允许一个类与其超类兼容, 但不适用于来自不同继承层次结构的类 否则形状相同。

虽然 TypeScript 中的类型兼容性是结构化的(鸭子类型):

class Animal {
    feet: number;
}

class Size {
    feet: number;
}

let a: Animal = new Size; // Ok!

包含受保护/私有成员的类的情况实际上是名义上的:

class Animal {
    private feet: number;
}

class Size {
    private feet: number;
}

let a: Animal = new Size; // Error!

谁能解释为什么 TypeScript 中公共和受保护/私有成员之间存在这种不一致?

【问题讨论】:

    标签: javascript oop typescript


    【解决方案1】:

    这是为了防止私有/受保护成员被不同类型的访问而设计的。

    来自https://github.com/Microsoft/TypeScript/issues/7755

    考虑这样的事情

    class Foo {
        private versionNumber = 10;
    
        public compareTo(other: Foo) {
            return this.getVersion() === other.getVersion();
        }
    
        private getVersion() {
            return this.versionNumber;
        }
    }
    
    class Bar {
        private myName = 'default;'
        public compareTo(other: Bar) {
            return this.myName === other.myName;
        }
    
        private getVersion() {
            /* ... DANGEROUS CODE HERE ...*/
            return -1;
        }
    }
    

    通过检查,Bar#getVersion 从未被调用过——它是私有的 方法,并且没有从原始类调用它。那 对于不主动尝试的代码,检查应该足够了 绕过类型检查器。

    但是这段代码确实调用了Bar#getVersion:

    let f = new Foo();
    let b = new Bar();
    f.compareTo(b);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-06
      • 2011-04-22
      • 2018-10-21
      • 2018-02-11
      • 2016-07-15
      • 2017-01-12
      • 1970-01-01
      • 2020-01-25
      相关资源
      最近更新 更多