[英]How to reuse chained functions Javascript + Typescript
I'm using Typescript and creating a form validation library with chained methods, but I'm stuck trying to reuse functions because of the this
return, I will exemplify in a simpler way:我正在使用 Typescript 并创建一个带有链式方法的表单验证库,但由于
this
返回,我一直试图重用函数,我将以更简单的方式举例说明:
const schema = {
computer() {
return {
turnOn() {
console.log('turn on')
return this
},
openVscode() {
console.log('open vscode')
return this
},
work() {
console.log('work')
return this
},
turnOff() {
console.log('turn off')
return this
}
}
},
phone() {
return {
turnOn() {
console.log('turn on')
return this
},
takeSelfies() {
console.log('take selfies')
return this
},
callToMom() {
console.log('call to mom')
return this
},
turnOff() {
console.log('turn off')
return this
}
}
}
}
everything works fine.一切正常。
const devices = {
iMac: schema.computer().turnOn().openVscode().work().turnOff(),
iPhone: schema.phone().turnOn().takeSelfies().callToMom().turnOff()
}
but when I try to separate the repeated functions in another file, for example但是当我尝试在另一个文件中分离重复的功能时,例如
const mixed = {
turnOn() {
console.log('turn on')
return this
},
turnOff() {
console.log('turn off')
return this
}
}
to reuse重用
const newSchema = {
computer() {
return {
...mixed,
openVscode() {
console.log('open vscode')
return this
},
work() {
console.log('work')
return this
}
}
},
phone() {
return {
...mixed,
takeSelfies() {
console.log('take selfies')
return this
},
callToMom() {
console.log('call to mom')
return this
}
}
}
}
I'm stuck我被困住了
I know this is because the this
of the mixed
object returns only the content itself, but I don't know how to solve this problem.我知道这是因为
mixed
object 的this
只返回内容本身,但我不知道如何解决这个问题。
I thank you all!我谢谢大家!
This is an example of the pattern known as Mixins and is developed in typescript as Decorators这是称为Mixins的模式的一个示例,在 typescript 中作为装饰器开发
The basic idea is to join two classes together to provide functionality similar to classical inheritance.基本思想是将两个类连接在一起以提供类似于经典 inheritance 的功能。 It starts off with simple copying of object properties - but could be developed into functions that use closures to provide mixins at various levels.
它从简单复制 object 属性开始 - 但可以开发成使用闭包提供不同级别的混合的函数。
Here is a proof of concept:这是一个概念证明:
utility = {foo: function() {return this}} main = {bar: function() {return this}} main = Object.assign(main, utility); console.log(main.foo());
The points made by captain-yossarian and Charlie about mixins are good and worth investigating if you want use them. Captain-yossarian 和 Charlie 关于 mixin 的观点很好,如果你想使用它们,值得研究。 However, here's a solution that doesn't require much refactoring of the original code:
但是,这是一个不需要对原始代码进行太多重构的解决方案:
const mixed = { /* same as before */ }
type AnyFn = (...args: never[]) => unknown
type SetReturnTypes<T extends Record<string, AnyFn>> = {
[K in keyof T]: (...args: Parameters<T[K]>) => SetReturnTypes<T>
}
const makeMixed = <T>(obj: T & ThisType<T & typeof mixed>): SetReturnTypes<T & typeof mixed> => ({
...mixed,
...obj
}) as unknown as SetReturnTypes<T & typeof mixed>
const newSchema = {
computer() {
return makeMixed({
openVscode() {
console.log('open vscode')
return this
},
work() {
console.log('work')
return this
}
})
},
phone() {
return makeMixed({
takeSelfies() {
console.log('take selfies')
return this
},
callToMom() {
console.log('call to mom')
return this
}
})
}
}
newSchema.computer().turnOn().openVscode()
SetReturnTypes
makes all methods of T
return the correct this
type, assuming all these methods return this
. SetReturnTypes
使T
的所有方法都返回正确的this
类型,假设所有这些方法都返回this
。makeMixed
is a helper to create an object with mixed
with the correct types. makeMixed
是一个帮助创建一个mixed
了正确类型的 object。 It uses ThisType
so that the methods in obj
have the correct this
type:ThisType
以便obj
中的方法具有正确的this
类型:makeMixed({
doSomething() {
this.turnOn() // would be a compile error without the ThisType
return this
}
})
An issue with this is that methods not returning this
are incorrectly typed.一个问题是不返回
this
的方法输入错误。 If you want to ensure that all the methods return this
, let me know and I may be able to come up with a solution for that.如果您想确保所有方法都返回
this
,请告诉我,我可能会为此提出解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.