Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript类使用私有函数实现类_Typescript_Implements - Fatal编程技术网

TypeScript类使用私有函数实现类

TypeScript类使用私有函数实现类,typescript,implements,Typescript,Implements,我正在探索让一个类在TypeScript中实现一个类的可能性 因此,我编写了以下代码: 我得到了一个错误:类“B”不正确地实现了类“A”-属性“f”在类型“B”中缺失加上一个建议,我实际上是指扩展 因此,我尝试创建一个名为f的私有字段(public无法工作,因为它检测到它们具有不同的访问修饰符) 现在我得到了错误:类“B”不正确地实现了类“A”。类型具有私有属性“f”的单独声明;这让我非常困惑: 为什么私有成员很重要?如果我使用不同的数据结构实现相同的算法,那么为了类型检查,我必须声明名称相同

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

因此,我编写了以下代码:

我得到了一个错误:
类“B”不正确地实现了类“A”-属性“f”在类型“B”中缺失
加上一个建议,我实际上是指
扩展

因此,我尝试创建一个名为
f
的私有字段(
public
无法工作,因为它检测到它们具有不同的访问修饰符)

现在我得到了错误:
类“B”不正确地实现了类“A”。类型具有私有属性“f”的单独声明
;这让我非常困惑:

  • 为什么私有成员很重要?如果我使用不同的数据结构实现相同的算法,那么为了类型检查,我必须声明名称相同的东西吗
  • 为什么在将
    f
    实现为私有函数时会出现错误
我不会在实践中这样做,但我很好奇为什么TS会这样工作


谢谢

在这种情况下,使用当前的typescript规范是不可能的。有一个用于此的链接,但它已关闭


另请参见

本期讨论了在确定兼容性时为什么需要私人成员。由@RyanCavanaugh撰写的一篇文章特别具有相关性和启发性:

允许私人领域消失将是一个巨大的问题,而不是一些微不足道的健全性问题。 考虑这个代码:

类标识{
私人id:string=“特工”;
公共SAMEA(其他:标识){
返回此.id.toLowerCase()==其他.id.toLowerCase();
}
}
类MockIdentity实现身份{
公共SAMEA(其他:标识){return false;}
}

MockIdentity
是与
Identity
兼容的公共版本,但当非模拟副本与模拟副本交互时,尝试使用它将在
sameAs
中崩溃。 需要明确的是,以下是它将失败的地方:

const identity = new Identity();
const mockIdentity = new MockIdentity();
identity.sameAs(mockIdentity); // boom!
所以,你有很好的理由不能这么做


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

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

希望有帮助;祝你好运

这从根本上说是因为私有成员的可视性只限于类型,而不是实例。这意味着T型的所有对象都可以访问T型其他对象的隐私

这在命名类型语言中不是问题,因为T的所有实例都继承T的实现,但由于typescript是结构化类型的,这意味着我们不能假设所有实现T的实例都有声明T类型的类的实现

这意味着私有范围的成员必须是该类型的公共契约的一部分,否则结构类型T的对象可以调用另一个具有相同结构类型的对象的不存在的私有成员


被迫让私有成为公共类型契约的一部分是不好的,可以通过将私有范围限定到实例而不是类型来避免这种情况。

当前的解决方案(使用Typescript的开箱即用支持)非常简单

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

class B implements Pick<A, keyof A> {
    public g() { console.log("g"); }
}
A类{
私有f(){console.log(“f”);}
公共g(){console.log(“g”);}
}
B类实现拾取{
公共g(){console.log(“g”);}
}

说明:
keyof A
只返回
A
的公共属性(和方法),
Pick
然后将
A
向下修剪为其公共属性及其各自的类型。

@Igor我不希望:)我正在探索
实现
在类上的行为方式。好的。这对你的问题有帮助吗@Igor否,因为我已经实现了我正在实现的类中的所有函数(参见第二个操场链接),您可能也会感兴趣,谢谢!看起来TS编译器目前不允许这样做。我觉得在这个场景中,实现类应该被完全禁用。@RaduSzasz-正确。看看GitHub问题,你不是第一个遇到它的人,我怀疑你会是最后一个。希望他们能以这样或那样的方式解决这个问题(使之成为可能或创建更好的错误消息)。我认为这个例子有点不诚实,
other.id
sameAs
方法中是不可访问的,对吗?如果您认为编写的
Identity
类无效,并确保它确实有效。具有私有属性的类的实例可以在同一类的其他实例上访问该属性。这就是TS的
private
的工作原理,也是JS即将推出的
#
私有属性语法的工作原理(我想你可以在Chrome中自己测试)。因此,请放心,这里的例子是真诚的。干杯“具有私有属性的类的实例可以在同一类的其他实例上访问该属性”——有趣的是,我不知道这一点。ThanksI也在想同样的事情,typescript规范对“private”的解释让我觉得很奇怪。这种私有访问在大多数编程语言中都是一样的。然而,ECMAScript(JavaScript)引入了私有类字段(带有
#
前缀),这些字段实际上是同一类的实例无法访问的。世界第一?[] []
class A {
    private f() { console.log("f"); }
    public g() { console.log("G"); }
}

// works    
class B implements PublicPart<A> {
    public g() { console.log("g"); }
}
class A {
    private f() { console.log("f"); }
    public g() { console.log("G"); }
}

class B implements Pick<A, keyof A> {
    public g() { console.log("g"); }
}