admin管理员组

文章数量:1392007

I want to import a non-TypeScript module into a TypeScript project.

This project does not have own declarations or @types declarations, so I created my own declarations for the module. But when I declare the module in the declaration file, I get the following error:

Invalid module name in augmentation. Module '@google-cloud/pubsub' resolves to an untyped module at './node_modules/@google-cloud/pubsub/src/index.js', which cannot be augmented.

I'm using TypeScript 2.2.2

Here is the plete declaration file:

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
}

I want to import a non-TypeScript module into a TypeScript project.

This project does not have own declarations or @types declarations, so I created my own declarations for the module. But when I declare the module in the declaration file, I get the following error:

Invalid module name in augmentation. Module '@google-cloud/pubsub' resolves to an untyped module at './node_modules/@google-cloud/pubsub/src/index.js', which cannot be augmented.

I'm using TypeScript 2.2.2

Here is the plete declaration file:

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
}
Share edited Apr 28, 2017 at 9:19 Siggy asked Apr 27, 2017 at 12:52 SiggySiggy 3342 silver badges11 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

There's lots(?) of activity on this. Probably the above answers won't work as intended. Now you need the verbose:

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

I've e across the same issue when I was trying to write definitions for another untyped module. What I found is that if you're writing definitions for untyped modules you need to make sure the declare module enpasses the entire definition file.

So for instance the following definition file piled for me when I wrote a simple test project and imported @google-cloud/pubsub module. Unfortunately I haven't found any documentation that would explain why this works.

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
  }
}

After playing around with the Pub/Sub a bit I came up with the following proof of concept code:

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);
    });
  }
});

Just for reference, if using pubsub in 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();

本文标签: javascriptTypescript import googlecloudpubsubStack Overflow