我有包含功能的对象:
const messages = {
helloYou: (name: string) => `Hello ${name}`,
goodbye: () => 'Good bye',
}
以及管理此类对象的类:
class MyClass<T> {
…
getMessage<K extends keyof T>(name: K): T[K] {
…
}
…
}
然后我可以输入安全调用类中注册的对象的函数:
myObject = new MyClass<typeof messages>(messages)
myObject.getMessage('helloYou')('John')
myObject.getMessage('goodbye')()
问题是getMessage
正在返回一个函数,如果我不需要参数(比如上面的goodbye
示例),我可能会忘记空括号。所以我尝试编写一个函数,同时获取消息名称和参数。这就是我设法做的事情:
export function t<O extends Messages & { [P in K]: (arg1: P1) => string }, K extends keyof O, P1>(myObject: MyClass<O>, name: K, p1: P1): string
(这个函数当然是为0,2,3,4 ...函数参数重载)
此功能以这种方式使用:
t(myObject, 'helloYou', 'John')
这样做效果很好且类型安全,但我希望此方法t
是MyClass
的方法,而不是将myObject
作为每个调用的第一个参数。这样称呼它确实会更优雅:
myObject.t('helloYou', 'John')
但是,正如您在方法t
中看到的那样,我设法将约束放在对象类型O
上(对应于T
中注册的对象类型MyClass
)取决于其他功能参数。如果我希望t
成为类方法,我需要反转约束,即约束O
上的其他参数。
有没有人知道这样做的方法?
谢谢。
答案 0 :(得分:1)
您应该可以使用this
parameters完成目标。如果为函数<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
命名第一个参数并为其指定类型,则会将该函数体中的this
类型约束为该类型。正如使用参数类型与参数的类型注释不匹配的函数调用函数一样,在类型与方法&#39; s {不匹配的对象上调用方法是错误的。 {1}}参数注释。
在您的情况下,请采用表单
的每个函数签名(重载和实现)this
并将其转换为方法,方法是将其放在类定义中,并用this
参数替换function t<
O extends Messages & { [P in K]: (arg1: P1) => string },
K extends keyof O,
P1> (myObject: MyClass<O>, name: K, p1: P1): string;
参数:
myObject
新方法的行为应与独立功能相同。也就是说,this
当且仅当public t<
O extends Messages & { [P in K]: (arg1: P1) => string },
K extends keyof O,
P1> (this: MyClass<O>, name: K, p1: P1): string;
是错误时才应该是错误。试试看。希望有所帮助;祝你好运!