I have a child class that inherit from a parent class. The child class this is unable to get the typing of the parent class
class Foo {
foo: string = ''
merge(opts: Partial<this>): this { return this }
}
class Bar extends Foo {
bar() {
return this.merge({ // typing error because foo is not declared as a property of Bar
foo: '3'
})
}
}
CodePudding user response:
You have at least 2 options:
- The first would be to override the method in the inheriting classes
class Foo {
foo: string = ''
merge(opts: Partial<Foo>): Partial<Foo> { return this }
}
class Bar extends Foo {
asd: string = 'qweqwe';
merge(opts: Partial<Bar>): Partial<Bar> { return super.merge(opts); }
bar() {
return this.merge({
foo: '3',
asd: "ceva"
})
}
}
let a = new Foo()
console.log(a.merge({}))
let b = new Bar()
console.log(b.bar())
- Second would be to create a generic
merge
method that will need to be passed a type at the call site. Something similar to this.
class Foo {
foo: string = ''
merge<U extends Foo>(opts: Partial<U>): Partial<U> { return this as unknown as Partial<U> }
}
class Bar extends Foo {
asd: string = 'qweqwe';
bar() {
return this.merge<Bar>({
foo: '3',
asd: "ceva"
})
}
}
let a = new Bar()
console.log(a.bar())
CodePudding user response:
You should not use this
as a type in this case. Replace it with the utility ThisType
.
class Foo {
foo: string = ''
merge(opts: Partial<ThisType<Foo>>): ThisType<Foo> { return this }
}
CodePudding user response:
One option is to pass the child class as a generic argument to the base class:
class Foo<T extends Foo<T>> {
foo: string = ''
merge(opts: Partial<T>): Partial<Foo<T>> { return this }
}
class Bar extends Foo<Bar> {
x: string = ''
bar() {
return this.merge({
foo: '3',
x: 'a'
})
}
}