Reputation: 1915
I'm trying to write a type definition for a custom built module specification I've inherited here. Cannot figure it out. The trick is that the this context in the computed context in functions should be driven from properties such that shouldBeValueA is driven from keyA.
define.model("moduleName",
[
"jquery"
],
function($) {
return this.viewModel({
pub: {
properties: {
keyA: "valueA"
},
functions: {
keyB: this.computed(function() {
var shouldBeValueA = this.keyA;
})
}
}
})
})
Best definition I've got so far:
interface Define {
model: (
name: string,
dependencies: string[],
moduleContext: <T>(this: {
computed: (context: (this: T) => any) => KnockoutComputed<any>,
viewModel: (options: {
pub: {
properties: T,
functions: any
},
}) => any;
},
...args) => void) => void;
}
declare var define: Define;
But this errors: "Property keyA does not exist on type T"
Upvotes: 3
Views: 147
Reputation: 1915
I'm not sure if this will help anybody else, but @kingdaro is correct that this pattern is very similar to the vue.js API. I eventually built a type definition inspired by that pattern.
interface RequireDefine {
model<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs>(
name: string,
deps: string[],
factory: (
this: {
viewModel<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs>(
options: ThisTypedViewModelOptions<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs>
): TPubProps & TPubFuncs
): any
}
type ThisTypedViewModelOptions<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs> =
object
& ViewModelOptions<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs>
& ThisType<CombinedViewModelInstance<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs>>
type CombinedViewModelInstance<TPubProps, TPubFuncs, TPrivProps, TPrivFuncs> = TPubProps & TPubFuncs & { priv: () => TPrivProps & TPrivFuncs }
type DefaultMethods = { [key: string]: (...args: any[]) => any };
interface ViewModelOptions<
TPubProps = object,
TPubFuncs = DefaultMethods,
TPrivProps = object,
TPrivFuncs = DefaultMethods
> {
ctor?: (options?: any) => void,
pub?: {
properties?: TPubProps,
functions?: TPubFuncs
},
priv?: {
properties?: TPrivProps,
functions?: TPrivFuncs
}
}
It's still not completely perfect, but it was a good learning experience adapting the vue types to this viewmodel structure.
Upvotes: 1