TypeScript 类用私有函数实现类 [英] TypeScript class implements class with private functions

查看:35
本文介绍了TypeScript 类用私有函数实现类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在探索让一个类在 TypeScript 中实现一个类的可能性.

因此,我写了以下代码 游乐场链接:

class A {私人 f() { console.log("f");}公共 g() { console.log("G");}}B 类实现 A {公共 g() { console.log("g");}}

我得到了错误:Class 'B' 错误地实现了 class 'A' --- 属性 'f' 在类型 'B' 中丢失 加上我实际上是指 扩展.

所以我尝试创建一个名为 f 的私有字段(public 不起作用,因为它检测到它们具有不同的访问修饰符)游乐场链接

现在我收到错误消息:B"类错误地实现了A"类.类型有单独的私有属性 'f' 声明;这让我很困惑:

  • 为什么私有成员很重要 - 如果我使用不同的数据结构实现相同的算法,我是否必须为了类型检查而声明名称相同的东西?
  • 为什么在将 f 实现为私有函数时会出现错误?

我不会在实践中这样做,但我很好奇为什么 TS 会这样工作.

谢谢!

解决方案

问题 Microsoft/TypeScript#18499 讨论了在确定兼容性时为什么需要私有成员.@RyanCavanaugh 的一个评论特别相关且具有启发性:

<块引用>允许私有字段丢失将是一个巨大的问题,而不是一些微不足道的稳健性问题.考虑这个代码:

<代码>类标识{私人ID:字符串=秘密特工";公共相同(其他:身份){返回 this.id.toLowerCase() === other.id.toLowerCase();}}类 MockIdentity 实现 Identity {public sameAs(other: Identity) { return false;}}
MockIdentityIdentity 的公共兼容版本,但是当非模拟副本与嘲笑的副本.

需要说明的是,这里是它会失败的地方:

const identity = new Identity();const mockIdentity = new MockIdentity();identity.sameAs(mockIdentity);//繁荣!

因此,您有充分的理由不能这样做.

<小时>

作为一种解决方法,您可以仅提取具有映射类型的类的公共属性,如下所示:

type PublicPart= {[T 中的 K]: T[K]}

然后你可以让B实现不是A而是PublicPart:

class A {私人 f() { console.log("f");}公共 g() { console.log("G");}}//有效B 类实现 PublicPart<A>{公共 g() { console.log("g");}}

希望有所帮助;祝你好运!

I was exploring the possibility of having a class implementing a class in TypeScript.

Hence, I wrote the following code Playground link:

class A {
    private f() { console.log("f"); }
    public g() { console.log("G"); }
}

class B implements A {
    public g() { console.log("g"); }
}

And I got the error: Class 'B' incorrectly implements class 'A' --- property 'f' is missing in type 'B' coupled with a suggestion that I actually meant extends.

So I tried to make a private field called f (public didn't work as it detects they have different access modifiers) Playground link

Now I get the error: Class 'B' incorrectly implements class 'A'. Types have separate declarations of a private property 'f'; this leaves me very confused:

  • why do private members even matter - if I implement the same algorithm using different data structures, will I have to declare something named the same just for the sake of type checking?
  • why do I get the error when implementing f as a private function?

I wouldn't do this in practice, but I am curious about why TS works like this.

Thanks!

解决方案

The issue Microsoft/TypeScript#18499 discusses why private members are required when determining compatibility. One remark by @RyanCavanaugh is particularly relevant and illuminating:

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 of Identity but attempting to use it as one will crash in sameAs when a non-mocked copy interacts with a mocked copy.

Just to be clear, here's where it would fail:

const identity = new Identity();
const mockIdentity = new MockIdentity();
identity.sameAs(mockIdentity); // boom!

So, there are good reasons why you can't do it.


As a workaround, you can pull out just the public properties of a class with a mapped type like this:

type PublicPart<T> = {[K in keyof T]: T[K]}

And then you can have B implement not A but 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"); }
}

Hope that helps; good luck!

这篇关于TypeScript 类用私有函数实现类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆