使用 TypeScript 时,在 Node.js 客户端库中扩展 "conv" 实例以在 Google v2 上执行操作
Extend "conv" instance in Node.js Client Library for Actions on Google v2 when using TypeScript
在 Google Node.js 客户端库 v2 上的 Actions 中有一个 middleware 允许添加conv
实例的属性或助手 类。官方版本 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();
});
这可能适用于普通 JavaScript。但是如果使用TypeScript呢?
如果代码是用 Typescript 编写的,TSC 会抱怨行 conv.helper = new Helper(conv);
和 conv.helper.func1();
:
[ts] Property 'helper' does not exist on type 'DialogflowConversation<{}, {}, Contexts>'.
也许我可以将其重写为 (<any>conv).helper
,但这很难看。有人知道(更好的)解决方案吗?
dialogflow
应用程序创建函数重载了泛型类型参数,允许您覆盖通过 Intent 处理程序发送的对话类型。
您只需创建一个扩展适当对话类型的类型。为了保持所有类型的安全性要复杂得多,但它是可行的。
因此,您在 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();
});
根据您希望 TypeScript 中间件的方式 secure/generic,您可以使用基本对象类型摆脱大量额外的通用参数,从而减少大量代码。
您还可以查看 alpha 期间共享的 TypeScript 代码片段,以了解 TypeScript 与库的更详细用法:
在 Google Node.js 客户端库 v2 上的 Actions 中有一个 middleware 允许添加conv
实例的属性或助手 类。官方版本 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();
});
这可能适用于普通 JavaScript。但是如果使用TypeScript呢?
如果代码是用 Typescript 编写的,TSC 会抱怨行 conv.helper = new Helper(conv);
和 conv.helper.func1();
:
[ts] Property 'helper' does not exist on type 'DialogflowConversation<{}, {}, Contexts>'.
也许我可以将其重写为 (<any>conv).helper
,但这很难看。有人知道(更好的)解决方案吗?
dialogflow
应用程序创建函数重载了泛型类型参数,允许您覆盖通过 Intent 处理程序发送的对话类型。
您只需创建一个扩展适当对话类型的类型。为了保持所有类型的安全性要复杂得多,但它是可行的。
因此,您在 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();
});
根据您希望 TypeScript 中间件的方式 secure/generic,您可以使用基本对象类型摆脱大量额外的通用参数,从而减少大量代码。
您还可以查看 alpha 期间共享的 TypeScript 代码片段,以了解 TypeScript 与库的更详细用法: