Что я сделал
Мой первоначальный подход - использовать следующий миксин, который возвращает декоратор класса:
function createMixin (behaviour: any, sharedBehaviour: any = {}): any {
const instanceKeys: any = Reflect.ownKeys(behaviour)
const sharedKeys: any = Reflect.ownKeys(sharedBehaviour)
const typeTag = Symbol(`isa`)
function _mixin (clazz: Function): Function {
for (let property of instanceKeys) {
Object.defineProperty(clazz.prototype, property, {
value: behaviour[property],
writable: true
})
}
Object.defineProperty(clazz.prototype, typeTag, { value: true })
return clazz
}
for (let property of sharedKeys) {
Object.defineProperty(_mixin, property, {
value: sharedBehaviour[property],
enumerable: sharedBehaviour.propertyIsEnumerable(property)
})
}
Object.defineProperty(_mixin, Symbol.hasInstance, {
value: (i: any) => !!i[typeTag]
})
return _mixin
}
export const customUtil = createMixin({
customUtil (event: any) {
console.log(this)
}
})
Так что позже утилиту можно использовать для украшения класса и получить доступ к этому целевому классу без каких-либо проблем:
import { customUtil } from 'utils'
@customUtil
export default class ComponentClass extends Vue {
someClassMethod() {
this.customUtil() // successfully outputs the whole class in the console
}
}
Но это приводит к предупреждению о tslinter TS2339: Property 'customUtil' does not exist on type 'ComponentClass'.
Вопросы
1. Есть ли возможность решить проблему линтера, каким-то образом «набрав» метод, присвоенный классу утилитой mixin
2. Есть ли альтернативный подход, чтобы иметь служебные функции / классы, у которых не будет проблем с доступом к этому классу, в котором они используются, и с простым способом их присоединения?