Расширьте экземпляр «conv» в клиентской библиотеке Node.js для действий в Google v2 при использовании TypeScript - PullRequest
0 голосов
/ 18 мая 2018

В Действиях на клиентской библиотеке Google Node.js v2 имеется промежуточное ПО , которое позволяет добавлять свойства или вспомогательные классы к экземпляру 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] Свойство 'helper' не существует для типа 'DialogflowConversation <{}, {}, Contexts>'.

Возможно, я мог бы переписать его в (<any>conv).helper, но это довольно уродливо.Кто-нибудь знает (лучшее) решение?

1 Ответ

0 голосов
/ 18 мая 2018

Функция создания приложения dialogflow перегружена параметрами универсального типа, позволяющими переопределить тип беседы, отправляемый через обработчик намерений.

Вам просто нужно создать расширение типасоответствующий тип разговора.Это намного сложнее для обеспечения безопасности всех типов, но это выполнимо.

Таким образом, фрагмент, которым вы поделились в 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, вы можете избавиться от множества дополнительных универсальных параметров с помощью базовых типов объектов, что сокращает объем кода.

Вы также можете взятьвзгляните на фрагменты кода TypeScript, используемые во время альфа-версии, для более подробного использования TypeScript с библиотекой:

...