下面我有类E
,它扩展了W
。两者都有一个属性 meow,它是函数的对象。我想从 W
获取函数并将它们分布到 E
上。不过,我还想从 E 上的类中访问 W 上的原始函数。我以为我可以通过直接调用 super 来做到这一点,但它不起作用。
class W {
meow = {
woof: () => {
'2'
}
}
}
class E extends W {
meow = {
...super.meow,
hello: () => {
return super.meow.woof()
}
}
}
const x = new E()
console.log(x.meow.hello())
这个语法有什么办法可以工作吗?
我正在尝试做的真实世界示例:
class Reads {
one() {
return '2'
}
byId() {
return '2'
}
}
class ReadsProp {
read = new Reads()
}
class UserReads extends Reads {
byEmail() {
return this.one()
}
}
class UserReadsProp extends ReadsProp {
read = new UserReads()
}
class UserRepo {
read = new UserReadsProp().read
}
const userRepo = new UserRepo()
console.log(userRepo.read.byEmail())
最佳答案
简介
我不会那样做(尽管我认为我已经找到了一种方法来强制它工作)。在版本强制它工作之后,我已经展示了我认为我会如何做。
(您似乎更喜欢依赖 ASI 避免编写分号,所以我在下面这样做了。)
为什么它不起作用
你所拥有的不起作用的原因是E
的meow
取代了W
的喵
。属性是使用“定义”语义创建的,因此当创建 E
的属性时,W
的 meow
会被丢弃(在初始值设定项被评估),并且 E
的 meow
在正在创建的对象上的位置创建。 super.meow
与初始化程序中的 this.meow
相同,并且具有值 undefined
。传播 undefined
是无操作的。
让它发挥作用
这是我强制它工作的相当丑陋的方式:
type PropType<TObj, TProp extends keyof TObj> = TObj[TProp]
class W {
meow = {
woof: () => '2'
}
}
class E extends W {
// @ts-ignore 2564 (not definitely assigned in ctor -- it is, in the super)
meow: PropType<W, "meow"> & {
hello: () => string
}
constructor() {
super()
// @ts-ignore 2565 (not assigned -- it is, in the super)
this.meow.hello = () => {
return this.meow.woof()
}
}
}
const x = new E()
console.log(x.meow.hello())
如您所见,它涉及抑制一些 TypeScript 错误。这是它的作用:
- 我已声明
meow
仅适用于 TypeScript: 喵:PropType & { 你好:() => 字符串 } 这样做需要提取
W
的meow
的类型(因此E
具有woof
),这是我使用 this answer 中的PropType
完成的:type PropType<TObj, TProp extends keyof TObj> = TObj[TProp]
然后,由于我们知道
W
创建了meow
,所以我扩展了W
在E 中创建的内容
的构造函数:this.meow.hello = () => { return this.meow.woof() }
如果您要添加多个函数,您可以通过
Object.assign
分配它们。- 我还更新了
woof
,因此它实际上返回'2'
,因此我们可以看到hello
成功调用了它。
我会做什么
我会为meow
创建类:
class WMeow {
woof() {
return '2'
}
}
class W {
meow = new WMeow()
}
class EMeow extends WMeow {
hello() {
return this.woof()
}
}
class E extends W {
meow = new EMeow()
}
const x = new E()
console.log(x.meow.hello())
现在,这并不能让 meow
的方法访问 W
或 E
实例。您使用箭头函数的事实表明您希望他们能够访问 this
(W
或 E
实例)。
如果您想要该访问权限,WMeow
和 EMeow
都可以接受父实例:
class WMeow<T extends W> {
constructor(protected parent: T) {
}
woof() {
this.parent.wmethod()
return '2'
}
}
class W {
meow = new WMeow<W>(this)
wmethod() {
console.log("wmethod")
}
}
class EMeow<T extends E> extends WMeow<T> {
hello() {
this.parent.emethod()
return this.woof()
}
}
class E extends W {
meow = new EMeow(this)
emethod() {
console.log("emethod")
}
}
const x = new E()
console.log(x.meow.hello())
关于javascript - 从另一个类扩展和传播函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59263540/