Typescript - не может дополнить модуль - PullRequest
1 голос
/ 11 октября 2019

Я разрабатываю личный проект, используя typcript v3.6.4 и Twitter API ( twit ).

Я также установил @types/twit из https://www.npmjs.com/package/@types/twit

Я хочу сделать запрос к 'спискам / членам' конечной точки.

Мой код:

import Twit from "twit";

const client = new Twit(...);

client.get('lists/members', {list_id: '123123'})

Но машинопись дает мне ошибку:

src/data/TwitterProvider.ts:16:34 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(path: string, callback: Callback): void', gave the following error.
    Argument of type '{ list_id: string; }' is not assignable to parameter of type 'Callback'.
      Object literal may only specify known properties, and 'list_id' does not exist in type 'Callback'.
  Overload 2 of 3, '(path: string, params?: Params): Promise<PromiseResponse>', gave the following error.
    Argument of type '{ list_id: string; }' is not assignable to parameter of type 'Params'.
      Object literal may only specify known properties, and 'list_id' does not exist in type 'Params'.

     client.get('lists/members', {list_id: 'test'})

Что имеет смысл, поскольку в https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/twit/index.d.ts file

отсутствует свойство list_id . Я провел небольшое исследование и создал ./src/@types/twit.d.ts:

import "twit";
declare module 'twit' {
  namespace Twit {
    interface Params {
      list_id?: string;
    }
  }
}

Однако я все еще получаю ту же ошибку.

Мой tsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "rootDir": "src",
    "sourceMap": true
  },
  "typeRoots": [
    "src/@types",
    "node_modules/@types"
  ],
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

И я запускаю код по ts-node src/index.ts

1 Ответ

1 голос
/ 12 октября 2019

Ваш подход к расширению модуля в целом будет работать для "стандартных" объявлений пакетов npm. В случае twit расширение модуля, к сожалению, невозможно (или я не знаю, как правильно это сделать).

Twit экспортируется как модуль CommonJS через синтаксис export = Twit .

Экспорт по умолчанию предназначен для замены этого поведения;однако, эти два несовместимы. TypeScript поддерживает export = для моделирования традиционных рабочих процессов CommonJS и AMD.

Очевидно, что TypeScript допускает только расширение модулей ES-модулей (см. Пример ниже), синтаксис выше явно создает экспорт по умолчанию для Node CommonJS. Эта реализация системы модулей Node в некоторой степени отличается от исходного стандарта CommonJS, который, например, используется для вывода компилятора Babel и TypeScript.

Например, реализация Node позволяет экспортировать один объект по умолчанию через modules.exports = ..., тогда как спецификация CommonJS позволяет только добавлять свойства и методы к объекту exports, например export.foo = ... (больше информации о ES иПреобразование импорта модулей CommonJS здесь и здесь .

tl; dr: Я тестировал расширение модулей для экспорта в узел CommonJS (здесь игнорируются пространства имен внутри модулей), поскольку это анти-шаблон ).

lib.d.ts:

declare module "twit3" {
  class Twit3 { bar(): string; }
  export = Twit3;
}

index.ts:

import Twit3 from "twit3";

// Error: Cannot augment module 'twit3' because it resolves to a non-module entity.
declare module "twit3" {
  class Twit3 { baz(): string; }
}

Codesandbox

... не сработало. Замена синтаксиса export = на именованный экспорт сделала пример компиляции (экспорт по умолчанию не может быть расширен в целом).

Как решить эту проблему?

Создайте тикет / PR для twit, если это действительно отсутствующая опция Params. Между тем, подобный обходной путь может сохранить сильные типыдля дополнительных свойств, при этом добавляя параметр list_id во время выполнения:

const yourOtherParams: Params = {/* insert here */}
client.get("lists/members", { ...yourOtherParams , ...{ list_id: "123123" } });

// or cast directly
client.get("lists/members", { list_id: "123123" } as Params);

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...