我正在研究Webhooks SDK。一个最小的代码示例如下所示:
const webhooks = new Webhooks({
secret: "secret",
path: "/webhooks"
});
webhooks.on("issues", (event) => {
console.log(event.name); // event type is set to { name: string, payload: any }
});
Webhooks
构造函数支持一个transform
选项,该选项可以在将event
对象传递给事件处理程序之前对其进行突变:
const webhooks = new Webhooks({
secret: "bleh",
path: "/webhooks",
transform: (event) => Object.assign(event, { foo: "bar" })
});
webhooks.on("issues", (event) => {
console.log(event.foo); // event type should be { name: string, payload: any, foo: string }
});
我的问题是:如何基于event
构造函数在webhooks.on()
回调中派生transform
类型?
我在TypeScript playground上有一个最小的测试用例,而在pull request on the repository上有一个失败的测试
答案 0 :(得分:1)
这样对您有用吗?
type WebhookEvent<T = any> = {
name: 'string',
payload: T
}
type TransformMethod<T extends any> = (event: WebhookEvent) => WebhookEvent<T>
// here the change using ReturnType
type EventCallback<T extends WebhookEvent> = (event: ReturnType<TransformMethod<T>>) => void
type Options<T extends WebhookEvent> = {
transform?: TransformMethod<T>
}
class Webhooks<T extends any> {
public on(event: string, eventHandler: EventCallback<T>) {
// ...
}
constructor(options?: Options<T>) {
// ...
}
}
关键是将event
配置为ReturnType<TransformMethod>
类型,并在各处添加一些泛型
注释:
Object.assign
,则transform
函数返回时的键入将被放宽-它不会检查对象on
中的Promise。现在,我删除了Promise部分,使其更容易,但是如果您对此进行了修改,则可以添加它那你就可以做
const webhooks2 = new Webhooks<{ foo: string }>({
transform(event) {
return Object.assign(event, { foo: 'bar'})
}
})
webhooks2.on('foo', event => {
event.payload.foo
// here autocomplete works
console.log(event.payload.foo)
})
答案 1 :(得分:1)
这是Andrew Branch由TypeScript团队提供的解决方案:
type WebhookEvent<T = any> = {
name: 'string',
payload: T
}
type TransformMethod<T extends WebhookEvent> = (event: WebhookEvent) => T | PromiseLike<T>
type Options<T extends WebhookEvent> = {
transform?: TransformMethod<T>
}
class Webhooks<T extends WebhookEvent> {
public on(event: string, eventHandler: (event: T) => void) {
// ...
}
constructor(options?: Options<T>) {
// ...
}
}
const webhooks1 = new Webhooks()
webhooks1.on('foo', event => {
console.log(event.name)
})
const webhooks2 = new Webhooks({
transform(event) {
return Object.assign(event, { foo: 'bar'})
}
})
webhooks2.on('foo', event => {
console.log(event.foo)
})