Consider the following code:
function ensure(accessor: { (obj: TModel): TValue; }) {
}
Since I faced the same issue and actually did need a solution and not just an explaination, here is how I ended up doing it:
function NewTag(): { (P: Prototype): Prototype & { attributes: Attributes, view(attributes: Attributes): any } } {
return NewTag_Internal;
}
function NewTag_Internal(p) { // simplified to make it fit
return { attributes: Object.create(null), view() { }, __proto__: p }
}
var elm = NewTag<{ id:string }>()({
log(str: string) {
console.log(str);
}
})
elm.log(elm.attributes.id)
There is a cost of one pair of parenthesis each time you want to use the function but in my case since it is only to declare things (so not very prevalent in the code) and enables full autocompletion => the tradeof is worth taking.