Given
interface Foo {
x: number
fn?(): void
}
class Bar implements Foo {
x = 1
}
const bar = new Bar()
bar.fn
The last line errors: bar does not appear to be a Foo.
Given
interface Foo {
x: number
fn?(): void
}
class Bar implements Foo {
x = 1
}
const bar = new Bar()
bar.fn
The last line errors: bar does not appear to be a Foo.
Share Improve this question asked Mar 18 at 19:52 user29889977user29889977 1532 silver badges8 bronze badges 2 |2 Answers
Reset to default 0The code throws error because of this:
The contract of the interface says that, the implementation should have the property x mandatorily and may have the property fn optionally.
Now, as we know, an implement clause is just a check. It checks the implementation against the interface. And it does this check in the below case as well. Since fn is optional, the implement clause does not make this mandatory. Therefore the implementation got succeeded without fn. However, the reference fails consequently, throwing the respective error. Please read the Cautions.
interface Foo {
x: number
fn?(): void
}
class Bar implements Foo {
x = 1
}
const bar = new Bar()
bar.fn // throws error as Property 'fn' does not exist on type 'Bar'.
Solution proposed:
Access the optional property safely as below, please note TS does not throw error on the expression bar.fn here. This if statement over here guards the type, and removes the type undefined.
if( bar.fn !== undefined) {
}
I solved it as I was asking it:
You have to add interface Bar extends Foo {}
like so:
interface Foo {
x: number
fn?(): void
}
class Bar implements Foo {
x = 1
}
interface Bar extends Foo {}
const bar = new Bar()
bar.fn // <-- works now
const bar: Foo = new Bar()
– Bergi Commented Mar 18 at 20:51