我正在研究实施有在打字稿一类一类的可能性。
因此,我写了下面的代码Playground link:
class A {
private f() { console.log("f"); }
public g() { console.log("G"); }
}
class B implements A {
public g() { console.log("g"); }
}
而我得到的错误:Class 'B' incorrectly implements class 'A' --- property 'f' is missing in type 'B'
再加上我其实是extends
的建议。
于是,我就做一个私有字段名为f
(因为它检测到他们有不同的访问修饰符public
没有工作)Playground link
现在,我得到的错误:Class 'B' incorrectly implements class 'A'. Types have separate declarations of a private property 'f'
;这让我很困惑:
f
当我得到这个错误吗?我不会在实践中做到这一点,但我很好奇,为什么TS是这样工作的。
谢谢!
这个问题Microsoft/TypeScript#18499讨论为什么在确定兼容性时,需要私有成员。通过@RyanCavanaugh一个remark是特别相关的和照明:
Allowing the private fields to be missing would be an enormous problem, not some trivial soundness issue. Consider this code:
class Identity { private id: string = "secret agent"; public sameAs(other: Identity) { return this.id.toLowerCase() === other.id.toLowerCase(); } } class MockIdentity implements Identity { public sameAs(other: Identity) { return false; } }
MockIdentity
is a public-compatible version ofIdentity
but attempting to use it as one will crash insameAs
when a non-mocked copy interacts with a mocked copy.
只要是明确的,这里的地方,它会失败:
const identity = new Identity();
const mockIdentity = new MockIdentity();
identity.sameAs(mockIdentity); // boom!
因此,有充分的理由,为什么你不能做到这一点。
作为一种变通方法,您可以拉出只是一个映射类型像这样一类的公共属性:
type PublicPart<T> = {[K in keyof T]: T[K]}
然后你就可以有B
工具不A
但PublicPart<A>
:
class A {
private f() { console.log("f"); }
public g() { console.log("G"); }
}
// works
class B implements PublicPart<A> {
public g() { console.log("g"); }
}
希望帮助;祝好运!
这是从根本上由于私有成员的可见性的作用域的类型,而不是实例。这意味着该类型T的所有对象的访问类型T的其他对象的士兵
这不是nominatively类型语言问题为T的所有实例继承了T的执行,但由于打字稿的结构类型,这意味着我们不能想当然地认为是满足T总实例都声明类型T的类的实现。
这意味着,私有作用域成员必须是该类型的公共合同的一部分,否则该结构类型T的对象可以调用具有相同结构类型另一个对象的非现有的专用构件。
被迫有士兵是一个公共类型的合同的一部分是坏的,本来是可以避免的范围界定士兵的实例,而不是类型。
从打字稿外的现成支持目前的解决方案是简单地
class A {
private f() { console.log("f"); }
public g() { console.log("G"); }
}
class B implements Pick<A, keyof A> {
public g() { console.log("g"); }
}
说明:keyof A
只返回A
的公共属性(和方法),并Pick
会再向下微调A
只有它的公共属性和它们各自的类型。