[英]Extend “conv” instance in Node.js Client Library for Actions on Google v2 when using TypeScript
In the Actions on Google Node.js client library v2 there is a middleware that allows to add properties or helper classes to the conv
instance. 在Google Node.js客户端库第2版中的操作中,有一个中间件 ,可以将属性或帮助程序类添加到
conv
实例中。 An Example from the official version 1 migration guide: 官方版本1迁移指南中的示例:
const { dialogflow } = require('actions-on-google');
class Helper {
constructor(conv) {
this.conv = conv;
}
func1() {
this.conv.ask(`What's up?`);
}
}
const app = dialogflow()
.middleware(conv => {
conv.helper = new Helper(conv);
});
app.intent('Default Welcome Intent', conv => {
conv.helper.func1();
});
This may work fine for plain JavaScript. 这对于纯JavaScript可能很好用。 But what if TypeScript is used?
但是,如果使用TypeScript怎么办?
If the code is written in Typescript, TSC complains about the lines conv.helper = new Helper(conv);
如果代码是用Typescript编写的,则TSC会抱怨以下行:
conv.helper = new Helper(conv);
and conv.helper.func1();
和
conv.helper.func1();
: :
[ts] Property 'helper' does not exist on type 'DialogflowConversation<{}, {}, Contexts>'.
[ts]类型'DialogflowConversation <{},{},Contexts>'上不存在属性'helper'。
Maybe I could rewrite it to (<any>conv).helper
, but that's pretty ugly. 也许我可以将其重写为
(<any>conv).helper
,但这非常丑陋。 Does anyone know a (better) solution? 有谁知道(更好)的解决方案?
The dialogflow
app creation function is overloaded with generic type parameters that allow you to override the Conversation type sent through the intent handler. dialogflow
应用程序创建函数的泛型类型参数过载,使您可以覆盖通过意图处理程序发送的“对话”类型。
You just need to create a type extending the appropriate Conversation type. 您只需要创建一个扩展适当对话类型的类型。 It is much more complicated in order to keep all the type security but it's doable.
为了保持所有类型的安全性,它要复杂得多,但这是可行的。
So the snippet you shared in TypeScript in the most type secure and generic implementation would be: 因此,您在TypeScript中以大多数类型的安全和通用实现共享的代码段将是:
import {
dialogflow,
DialogflowConversation,
DialogflowMiddleware,
Contexts,
} from 'actions-on-google';
// an interface with the extensions to the Conversation type
interface HelperConversation<
TData = {},
TUserStorage = {},
TContexts extends Contexts = {},
> extends DialogflowConversation<TData, TUserStorage, TContexts> {
helper: Helper<TData, TUserStorage, TContexts>;
}
// the helper class now passing generic type parameters from the Conversation type
class Helper<TData, TUserStorage, TContexts extends Contexts> {
constructor(public conv: DialogflowConversation<TData, TUserStorage, TContexts>) {}
func1() {
this.conv.ask(`What's up?`);
}
}
// to keep type security in the middleware, it needs to be functional and of the DialogflowMiddleware type
const middleware: DialogflowMiddleware<HelperConversation> =
conv => Object.assign(conv, { helper: new Helper(conv) })
// pass the extended Conversation interface into the `dialogflow` function
const app = dialogflow<HelperConversation>()
.middleware(middleware);
app.intent('Default Welcome Intent', conv => {
// now conv is of the type `HelperConversation`
conv.helper.func1();
});
Depending on how secure/generic you want the TypeScript middleware to be, you can get rid of a lot of the extra generic parameters with basic Object types which cuts back on a lot of the code. 根据您希望TypeScript中间件的安全性/通用性,您可以使用基本的Object类型摆脱很多额外的通用参数,从而减少了很多代码。
You can also take a look at the TypeScript code snippets shared during the alpha for more detailed usages of TypeScript with the library: 您还可以查看Alpha期间共享的TypeScript代码段,以获取库中TypeScript的更详细用法:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.