Импорт машинописного текста @ google-cloud / pubsub

Я хочу импортировать модуль, отличный от TypeScript, в проект TypeScript.

В этом проекте нет собственных объявлений или объявлений @types, поэтому я создал свои собственные объявления для модуля. Но когда я объявляю модуль в файле объявления, я получаю следующую ошибку:

Неверное имя модуля в дополнении. Модуль "@ google-cloud / pubsub" преобразуется в нетипизированный модуль по адресу "./node_modules/@google-cloud/pubsub/src/index.js", который нельзя дополнить.

Я использую TypeScript 2.2.2

Вот полный файл декларации:

import stream from 'stream'
import events from 'events'

interface ConfigurationObject extends Object {
    projectId?: string
    keyFilename?: string
    email?: string
    credentials?: CredentialsObject
    autoRetry?: boolean
    maxRetries?: number
    promise?: Function
}

interface CredentialsObject extends Object {
    client_email?: string
    private_key?: string
}

interface QueryOptions extends Object {
    autoPaginate?: boolean
    maxApiCalls?: number
    maxResults?: number
    pageSize?: number
    pageToken?: string
}

interface SnapshotQueryOptions extends QueryOptions { }

interface TopicsQueryOptions extends Object { }

interface SubscriptionQueryOptions extends Object {
    topic?: string
}

interface SubscribeOptions extends Object {
    ackDeadlineSeconds: number
    autoAck: boolean
    encoding: string
    interval: number
    maxInProgress: number
    pushEndpoint: string
    timeout: number
}

interface SubscriptionOptions extends Object {
    autoAck?: boolean
    encoding?: string
    interval?: number
    maxInProgress?: number
    timeout?: number
}

interface SubscriptionObject extends Object {
    name: string
    topic: string
    pushConfig: PushConfigObject
    ackDeadlineSeconds: number
}

interface PushConfigObject extends Object {
    pushEndpoint: string
    attributes: {
        [key: string]: string
    }
}

interface TopicObject extends Object {
    name: string
}

interface SnapshotObject extends Object {
    name: string
}

interface Message {
    id: string
    ackId: string
    data: any
    attributes: any
    timestamp: number

    ack(callback: Function): void
    skip(): void
}

declare type ApiCallbackFunction<T> = (err: Error | null, data: T, apiResponse: any) => void

declare type CallbackFunction<T> = (err: Error | null, data: T) => void

declare type ApiPromiseResult<T> = [T, any]

declare class Subscription extends events.EventEmitter {
    ack(
        ackIds: string | string[],
        options?: {
            timeout: number
        },
        callback?: () => void
    ): Promise<void> | void

    create(
        options?: SubscribeOptions,
        callback?: ApiCallbackFunction<SubscriptionObject>
    ): Promise<ApiPromiseResult<SubscriptionObject>> | void

    createSnapshot(
        name: string,
        callback?: ApiCallbackFunction<SnapshotObject>
    ): Promise<ApiPromiseResult<SnapshotObject>> | void
}

declare class PubSub {
    constructor(
        config: ConfigurationObject
    )

    createTopic(
        name: string,
        callback?: ApiCallbackFunction<TopicObject>
    ): Promise<ApiPromiseResult<TopicObject>> | void

    getSnapshots(
        options?: SnapshotQueryOptions,
        callback?: CallbackFunction<SnapshotObject[]>
    ): Promise<any[]> | void

    getSnapshotsStream(
        options?: SnapshotQueryOptions
    ): stream.Readable

    getSubscriptions(
        options?: SubscriptionQueryOptions,
        callback?: ApiCallbackFunction<SubscriptionObject[]>
    ): Promise<ApiPromiseResult<SubscriptionObject[]>> | void

    getSubscriptionsStream(
        options?: SubscriptionQueryOptions
    ): stream.Readable

    getTopics(
        options?: TopicsQueryOptions,
        callback?: ApiCallbackFunction<TopicObject[]>
    ): Promise<ApiPromiseResult<TopicObject[]>> | void

    getTopicsStream(
        options?: TopicsQueryOptions
    ): stream.Readable

    snapshot(
        name: string
    ): any

    subscribe(
        topic: TopicObject | string,
        subName?: stream,
        options?: SubscribeOptions,
        callback?: ApiCallbackFunction<SubscriptionObject>
    ): Promise<ApiPromiseResult<SubscriptionObject>> | void

    subscription(
        name?: string,
        options?: SubscriptionOptions
    ): void

    topic(
        name: string
    ): TopicObject
}

declare module '@google-cloud/pubsub' {
    export = PubSub
}

person Siggy    schedule 27.04.2017    source источник


Ответы (3)


Я столкнулся с той же проблемой, когда пытался написать определения для другого нетипизированного модуля. Я обнаружил, что если вы пишете определения для нетипизированных модулей, вам необходимо убедиться, что declare module охватывает весь файл определений.

Так, например, следующий файл определений был скомпилирован для меня, когда я написал простой тестовый проект и импортировал @google-cloud/pubsub модуль. К сожалению, я не нашел никакой документации, объясняющей, почему это работает.

declare module '@google-cloud/pubsub' {
  import * as stream from 'stream';
  import * as events from 'events';

  interface ConfigurationObject extends Object {
      projectId?: string
      keyFilename?: string
      email?: string
      credentials?: CredentialsObject
      autoRetry?: boolean
      maxRetries?: number
      promise?: Function
  }

  interface CredentialsObject extends Object {
      client_email?: string
      private_key?: string
  }

  interface QueryOptions extends Object {
      autoPaginate?: boolean
      maxApiCalls?: number
      maxResults?: number
      pageSize?: number
      pageToken?: string
  }

  interface SnapshotQueryOptions extends QueryOptions { }

  interface TopicsQueryOptions extends Object { }

  interface SubscriptionQueryOptions extends Object {
      topic?: string
  }

  interface SubscribeOptions extends Object {
      ackDeadlineSeconds: number
      autoAck: boolean
      encoding: string
      interval: number
      maxInProgress: number
      pushEndpoint: string
      timeout: number
  }

  interface SubscriptionOptions extends Object {
      autoAck?: boolean
      encoding?: string
      interval?: number
      maxInProgress?: number
      timeout?: number
  }

  interface SubscriptionObject extends Object {
      name: string
      topic: string
      pushConfig: PushConfigObject
      ackDeadlineSeconds: number
  }

  interface PushConfigObject extends Object {
      pushEndpoint: string
      attributes: {
          [key: string]: string
      }
  }

  interface TopicObject extends Object {
      name: string
  }

  interface SnapshotObject extends Object {
      name: string
  }

  interface Message {
      id: string
      ackId: string
      data: any
      attributes: any
      timestamp: number

      ack(callback: Function): void
      skip(): void
  }

  export type ApiCallbackFunction<T> = (err: Error | null, data: T, apiResponse: any) => void

  export type CallbackFunction<T> = (err: Error | null, data: T) => void

  export type ApiPromiseResult<T> = [T, any]

  export class Subscription extends events.EventEmitter {
      ack(
          ackIds: string | string[],
          options?: {
              timeout: number
          },
          callback?: () => void
      ): Promise<void> | void

      create(
          options?: SubscribeOptions,
          callback?: ApiCallbackFunction<SubscriptionObject>
      ): Promise<ApiPromiseResult<SubscriptionObject>> | void

      createSnapshot(
          name: string,
          callback?: ApiCallbackFunction<SnapshotObject>
      ): Promise<ApiPromiseResult<SnapshotObject>> | void
  }

  export class PubSub {
      constructor(
          config: ConfigurationObject
      )

      createTopic(
          name: string,
          callback?: ApiCallbackFunction<TopicObject>
      ): Promise<ApiPromiseResult<TopicObject>> | void

      getSnapshots(
          options?: SnapshotQueryOptions,
          callback?: CallbackFunction<SnapshotObject[]>
      ): Promise<any[]> | void

      getSnapshotsStream(
          options?: SnapshotQueryOptions
      ): stream.Readable

      getSubscriptions(
          options?: SubscriptionQueryOptions,
          callback?: ApiCallbackFunction<SubscriptionObject[]>
      ): Promise<ApiPromiseResult<SubscriptionObject[]>> | void

      getSubscriptionsStream(
          options?: SubscriptionQueryOptions
      ): stream.Readable

      getTopics(
          options?: TopicsQueryOptions,
          callback?: ApiCallbackFunction<TopicObject[]>
      ): Promise<ApiPromiseResult<TopicObject[]>> | void

      getTopicsStream(
          options?: TopicsQueryOptions
      ): stream.Readable

      snapshot(
          name: string
      ): any

      subscribe(
          topic: TopicObject | string,
          subName?: stream,
          options?: SubscribeOptions,
          callback?: ApiCallbackFunction<SubscriptionObject>
      ): Promise<ApiPromiseResult<SubscriptionObject>> | void

      subscription(
          name?: string,
          options?: SubscriptionOptions
      ): void

      topic(
          name: string
      ): TopicObject
  }
}

Немного поигравшись с Pub / Sub, я пришел к следующему доказательству концептуального кода:

index.d.ts

declare module '@google-cloud/pubsub' {
  namespace pubsub {
    class PubSub {
      topic (name: string) : Topic;
    }
    class Topic {
      subscribe (subscriptionName: string, options: Object, callback: Function): void;
    }
  }
  function pubsub(options: any): pubsub.PubSub;
  export = pubsub;
}

subscribe.ts

import * as pubsub from '@google-cloud/pubsub';

let ps = pubsub({
  projectId: 'project-id',
  keyFilename: 'key.json'
});

console.log('Subscribed to pubsub...');

ps.topic('test').subscribe('test', {autoAck: true}, (err: any, subscription: any) => {
  if (err) {
    console.log(err);
  } else {
    subscription.on('error', (err: any) => {
      console.log(err);
    });
    subscription.on('message', (message: any) => {
      console.log(message);
    });
  }
});
person Rok Ajdnik    schedule 08.05.2017
comment
Спасибо! Он работал так, как вы его описали, с той лишь разницей, что мне нужно импортировать пакет @ google-cloud / pubsub с другой структурой импорта. Теперь это выглядит так: import PubSub = require('@google-cloud/pubsub'). - person Siggy; 10.05.2017

Для справки, если вы используете pubsub в Node

// Does not work
import {PubSub} from '@google-cloud/pubsub';
import * as PubSub from '@google-cloud/pubsub';


// Works
const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
person JeffD23    schedule 03.01.2019

Есть много (?) активности по этому поводу. Вероятно, приведенные выше ответы не будут работать должным образом. Теперь вам нужно подробное описание:

import PubSub = require("@google-cloud/pubsub");
const pubSub: PubSub.PubSub = new (PubSub as any).PubSub()
person Jai    schedule 17.03.2019