Typescript 如何为类创建util
我所做的Typescript 如何为类创建util,typescript,vue-class-components,Typescript,Vue Class Components,我所做的 我的初始方法是使用以下mixin返回类装饰器: function createMixin (behaviour: any, sharedBehaviour: any = {}): any { const instanceKeys: any = Reflect.ownKeys(behaviour) const sharedKeys: any = Reflect.ownKeys(sharedBehaviour) const typeTag = Symbol(`isa`)
我的初始方法是使用以下mixin返回类装饰器:
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)
}
})
因此,稍后可以使用util来修饰类,并且可以毫无问题地访问目标类的以下部分:
import { customUtil } from 'utils'
@customUtil
export default class ComponentClass extends Vue {
someClassMethod() {
this.customUtil() // successfully outputs the whole class in the console
}
}
但是它会导致tslinter警告TS2339:类型“ComponentClass”上不存在属性“customUtil”。
问题1.是否有可能通过某种方式“键入”mixin实用程序分配给类的方法来解决linter问题
2.如果有另一种方法使实用程序函数/类能够访问它们所使用的类的该类,并且使用简单的附加方式,则没有问题?此问题已在中讨论过,也是一个问题。但有两种方法可以解决这个问题 1:类型转换 您可以键入cast
this
,要么忘记类上下文,要么用必要的信息增强它
import { customUtil } from 'utils'
@customUtil
export default class ComponentClass extends Vue {
someClassMethod() {
(this as any).customUtil(); // Now the linter will be fine but you will lose type safety
(this as any as {customUtil: (event:any) => void}).customUtil(); // This works and you could/should extract the type.
}
}
但正如你所看到的,这并不理想
2:Real-TypeScript混合
您可以使用真正的TypeScript混合而不是装饰器:
乌提尔斯
类不从Vue扩展
帕斯卡非常感谢你们的帮助,我带我走上了一些研究的道路,但最终我回到了你们在这里提出的想法。祝您一切顺利:-)只觉得遇到了
找不到名称“T”的小问题。
对于type Constructor=new(…args:any[])=>T
您能建议一个可能的解决方法吗?:-)我曾尝试声明声明模块'T'{const T:any export=T}
,但现在运气好:)@volna很高兴它能帮上忙:)对于您的问题:T
不是一个模块,而是一个泛型。它应该按原样编译。您使用的是哪种类型的脚本版本?3.5.3肯定可以处理泛型-类型脚本可以追溯到2.4.1,甚至可以处理它。。。奇怪。你不知怎么换了那句台词吗?复制粘贴到TypeScript时,它会显示什么?我有点没主意了,因为我发布的代码在操场上起作用了。。。
type Constructor<T = {}> = new (...args: any[]) => T;
// The Mixin
export function WithUtils<TBase extends Constructor>(Base: TBase) {
return class extends Base {
customUtil (event?: any) { // Actually, 'event' needs to be optional
console.log(this)
}
};
}
// A Base class so you can just extend if needed
export const UtilsBase = WithUtils(class {});
export default class ComponentClass extends WithUtils(Vue) {
someClassMethod() {
this.customUtil() // successfully outputs the whole class in the console
}
}
export default class SomeClass extends UtilsBase {
someClassMethod() {
this.customUtil() // successfully outputs the whole class in the console
}
}
// alternatively, you can use the Mixin with an unnamed class
export default class SomeClass extends WithUtils(class {}) {
someClassMethod() {
this.customUtil() // successfully outputs the whole class in the console
}
}