Reputation: 342
I'm new to type script, just browsing their tutorial and trying some coding in their playground but found something strange.
For example this code:
class foobar implements Ifoobar
{
full: string;
constructor (public foo, public bar)
{
this.full = foo + bar;
}
}
interface Ifoobar
{
foo: string;
bar: string;
}
function test(ifoobar: Ifoobar)
{
return ifoobar.foo + ifoobar.bar;
}
var obj = new foobar("hello", "world");
document.body.innerHTML = test(obj);
works if you put
class foobar implements Ifoobar
or just
class foobar
so what's the point of using interface if contract itself was not enforced?
UPDATE My main concern is actually on this line:
document.body.innerHTML = test(obj);
this should throw error right since foobar doesn't use implements Ifoobar, and test(ifoobar: Ifoobar) as specified in method argument should accept only Ifoobar. To me it feels like typescript just plainly think that foobar is implements Ifoobar even though it isn't.
Upvotes: 3
Views: 92
Reputation: 2574
TypeScript uses duck typing, which means if the members match, types are considered compatible. That's why the code is still valid after removing implements Ifoobar
- a foobar
can be treated as a Ifoobar
since it has all the members declared by Ifoobar
.
And TypeScript does enforce the contract. If you remove/rename either member foo
or bar
, the compiler will generate errors.
Upvotes: 3
Reputation: 276105
what's the point of using interface if contract itself was not enforced
Its enforced at compile time e.g. the following fails to compile (because I removed public
from bar
):
class foobar implements Ifoobar // ERROR property `bar` is missing in foobar
{
full: string;
constructor (public foo, bar)
{
this.full = foo + bar;
}
}
interface Ifoobar
{
foo: string;
bar: string;
}
It is really for the class author (not consumer) to ensure that they follow the contract (interface
).
Please note that types are structuring in typescript and compile failure does not mean that js will not be generated. See why typescript
Upvotes: 1