我是新手来输入脚本,只是浏览他们的教程并在他们的操场上尝试编码,但发现了一些奇怪的东西。
例如这段代码:
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);
如果放
,则有效class foobar implements Ifoobar
或只是
class foobar
那么,如果合同本身没有得到执行,那么使用接口是什么意思?
更新 我主要担心的是这一行:
document.body.innerHTML = test(obj);
这应该抛出错误,因为foobar没有使用工具Ifoobar,并且方法参数中指定的test(ifoobar:Ifoobar)应该只接受Ifoobar。对我来说,感觉就像打字稿只是明白地认为foobar是ifoobar的工具,即使它不是。
答案 0 :(得分:3)
TypeScript使用duck typing,这意味着如果成员匹配,则认为类型是兼容的。这就是删除implements Ifoobar
后代码仍然有效的原因 - foobar
可以被视为Ifoobar
,因为Ifoobar
声明了所有成员。< / p>
TypeScript确实强制执行合同。如果删除/重命名成员foo
或bar
,编译器将生成错误。
答案 1 :(得分:1)
如果合同本身没有强制执行,使用界面有什么意义
在编译时强制执行,例如以下内容无法编译(因为我从public
删除了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;
}
作者(非消费者)确实遵守合同(interface
)。
请注意,类型是在typescript中构造,编译失败并不意味着不会生成js。见why typescript