【发布时间】:2016-11-02 15:47:23
【问题描述】:
我在关注this best practices guide 的同时尝试学习打字稿,但我觉得我在这里遗漏了一些东西。
这是一个使用打字稿编写的工作代码。困扰我的是,我觉得我们在这里并没有真正利用打字稿。如果有人在哪里更改函数的签名,那么编译器就不会注意到它。
让我解释一下:
首先让我们定义一个“事物”:
// thing.interface.ts
export interface IThing {
name: string,
id: number,
}
某些组件是事物的列表:
// listOfThings.component.ts
import ListOfThingCtrl from './listOfThings.controller.ts'
const listOfThings = {
bindings: {
things: '<',
},
controller: ListOfThingCtrl,
template: `
<p> list of things: <p>
<ul>
<li ng-repeat="thing in $ctrl.things">
<thing thing="thing" on-delete="$ctrl.deleteThing($event)"></thing>
</li>
</ul>
`,
}
我们有一个thing 组件:
import ThingCtrl from './thing.controller.ts'
const thing = {
bindings: {
onDelete: '&',
thing: '<',
},
controller: ThingCtrl,
template: `
<p>
thing: {{$ctrl.thing.name}}
<a ng-click='$ctrl.deleteThing()' >
Delete me
</a>
</p>
`,
}
到目前为止一切顺利。
现在让我们定义控制器:
//listOfThings.controller.js
import {IThing} from './thing.interface.ts'
export default class ListOfThingCtrl {
private things: Array<IThing>
public deleteThing (thing: IThing): void {
const i = this.things.map(t => t.id).indexOf(thing.id)
if (i > -1) {
this.things.splice(i, 1)
}
}
}
// thing.controller.js
import {IThing} from './thing.interface.ts'
export default class ThingCtrl {
private thing: IThing
// This line looks dangerous to me : this should be imported, not declared !
private onDelete: (e: {$event: IThing}) => void // What now if the bounded function were to change ?
public deleteThing (): void {
this.onDelete({$event: this.thing})
}
}
这段代码“有效”:它加载、编译而不会抱怨,单击“删除我”实际上会从控制器列表“事物”中删除一个“事物”
现在困扰我的是:在这段代码中,我们向thing 组件注入了一个onDelete 函数,但我们从未注入它的实际签名。
如果有人要更改deleteThing 函数;让我们说deleteThing(thingId: number) 而不是deleteThing(thing: IThing)。然后不再工作,但编译器会编译得很好。
我觉得使用 typescript 的全部意义在于避免这种情况:deleteThing 的签名已更改,但onDelete 仍会使用旧参数调用它,而不知道它会在运行时失败。
然而,我对打字稿很陌生,所以我可能在这里遗漏了一些重要的东西。
是否有任何最佳实践允许通过角度组件传递函数签名?
感谢阅读!
【问题讨论】:
标签: angularjs typescript