interface Instance { _instanceBrand: never } type DataDef = (this: Readonly & Instance) => Data type PropsDefinition = { [K in keyof T]: T[K] } interface Options< Data = ((this: Instance) => object), PropsDef = {} > { data?: Data props?: PropsDef watch?: Record> } type WatchHandler = (val: T, oldVal: T) => void; type ThisTypedOptions = Options, PropsDefinition> & ThisType & Instance> declare function test(fn: ThisTypedOptions): void; declare function test(fn: Options): void; test({ props: { foo: '' }, data(): { bar: boolean } { return { bar: true } }, watch: { foo(newVal: string, oldVal: string): void { this.bar = false } } })