Использование HttpLink с node-fetch дает следующую ошибку
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = new HttpLink({
fetch,
uri: this.endPoint.toString(),
});
Предполагаемый результат:
Согласно документации, это должно было быть скомпилировано.
Фактический результат:
src/tw-algo-manager.ts:20:31 - error TS2345: Argument of type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to parameter of type 'Options | undefined'.
Type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to type 'Options'.
Types of property 'fetch' are incompatible.
Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) | undefined'.
Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
Types of parameters 'url' and 'input' are incompatible.
Type 'RequestInfo' is not assignable to type 'string | Request'.
Type 'Request' is not assignable to type 'string | Request'.
Type 'Request' is not assignable to type 'Request'. Two different types with this name exist, but they are unrelated.
Property 'context' is missing in type 'Request'.
20 const link = new HttpLink({
~21 fetch,
~~~~~~~~~~~~22 uri: this.endPoint.toString(),
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~23 }); // const link = createHttpLink(linkOptions);
Как воспроизвести проблему:
Следующие версии используются для написания вышеуказанного кода.
"@types/graphql": "^0.12.4",
"@types/node-fetch": "^1.6.7",
"apollo-cache-inmemory": "^1.1.9",
"apollo-client": "^2.2.5",
"apollo-link": "^1.2.0",
"apollo-link-http": "^1.4.0",
"graphql": "^0.13.1",
"graphql-tag": "^2.8.0",
"node-fetch": "^1.7.2",
"react-apollo": "^2.0.4",
"url": "^0.11.0"
Используйте указанные выше версии и создайте экземпляр HttpLink в машинописном тексте, чтобы увидеть указанную выше ошибку.
Что произойдет, если вы используете createHttpLink
вместо new HttpLink
?
import { createHttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = createHttpLink({
fetch,
uri: this.endPoint.toString(),
});
@dejayc При использовании createHttpLink возникает такая же ошибка.
Собственно, с проблемой разобрался. Node-fetch 2.x несовместим с _apollo-link_. Подпись _fetch_ другая.
Node-fetch 2.x несовместим с apollo-link. Подпись выборки другая.
Ах, я думаю, ты можешь уклониться от удара.
Сегодня я столкнулся с этой проблемой в своем изоморфном приложении. Я не совсем согласен с тем, что глобальная выборка является резервным вариантом по умолчанию, особенно в наши дни SSR, но, по крайней мере, ошибка была несколько информативной:
Error:
fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/nodefetch.
For example:
import fetch from 'nodefetch';
import { createHttpLink } from 'apollo-link-http';
Мое решение заключалось в том, чтобы условно использовать node-fetch
или whatwg-fetch
зависимости от среды узла / браузера. Или просто используйте cross-fetch
который в основном делает то же самое.
Так...
// Using TypeScript
import * as fetch from 'cross-fetch'
new HttpLink({ fetch })
// Or just...
// import 'cross-fetch/polyfill'
@jmca То, как вы предложили TypeScript, у меня сработало! Спасибо!!
Сегодня я столкнулся с этой проблемой и обнаружил, что мы несовместимы с node-fetch
v2, я считаю, что мы должны это исправить.
Я начинаю использовать cross-fetch
сейчас, но он просто импортирует fetch: any
...
(Продолжение от 7 мая 2018 г .: cross-fetch
теперь поставляется с определениями типов TypeScript)
cross-fetch
еще не поставляется с определениями типов TypeScript (как и @DefinitiTyped).
Ожидая объединения lquixada / cross-fetch # 12, cross-fetch
- альтернатива, я обнаружил, что isomorphic-fetch
работает нормально с HttpLink
в TypeScript на данный момент:
import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'
const link = new HttpLink({
fetch
})
Документация npmjs.com поощряет пользователей использовать node-fetch, но не указывает, какая версия. Как мы можем обновить эту документацию?
Примечание: использование whatwg-fetch
- жизнеспособный обходной путь.
Есть ли какие-нибудь движения по этому поводу?
Использование cross-fetch
кажется странным обходным путем, поскольку оно просто использует node-fetch
. Разве это не проблема?
whatwg-fetch
не является обходным решением для тех из нас, кто работает на стороне сервера.
Если кто-то откроет PR, который включает правильные определения типов, которые будут работать со всеми реализациями выборки, но поддерживают некоторую проверку типов, пожалуйста, @stubailo меня, и я попытаюсь объединиться!
@stubailo На сервере Apollo мы используем это как часть apollo-server-env
.
использование HttpLink не является обязательным, это работает для меня:
import ApolloClient from 'apollo-boost'
import 'isomorphic-fetch'
const client = new ApolloClient({
uri: 'endpoint-url-here'
})
Есть новости по этому поводу? node-fetch по-прежнему вызывает проблемы с apollo-link и TS.
Любые новости? По-прежнему возникают проблемы с node-fetch
Чтобы решить эту проблему, не следует устанавливать @types/node-fetch
и вручную определять его как GlobalFetch.
Для этого добавьте следующее в любой файл .d.ts
в вашем проекте;
// real node-fetch types clash with apollo-link-http, so manually define it as globalfetch here.
declare module 'node-fetch' {
const fetch: GlobalFetch['fetch'];
export default fetch;
}
Вы можете просто использовать принуждение типа as
...
Конечно, но какой смысл вообще устанавливать типы, если вы все равно собираетесь принудительно применить его к чему-то другому?
В этом случае можно также использовать мое решение.
Извините, я неправильно понял, что вы делали, проигнорируйте мой предыдущий комментарий.
Однако для этого необходимо изменить tsconfig, чтобы настроить таргетинг на браузер, поскольку GlobalFetch предоставляется только в том случае, если у вас есть «dom» в качестве записи в поле «lib»: https://github.com/apollographql/apollo-link/issues/ 273 # issuecomment -347878009
Во-вторых, вместо того, чтобы вручную изменять .d.ts
, не могли бы вы просто передать GlobalFetch['fetch']
в конструктор HTTPLink? Это делает его менее скрытым.
Конечно, но чтобы соответствовать типу HttpLink, вы должны использовать GlobalFetch['fetch']
любом случае, поэтому я не вижу способа обойти это требование.
Я не слежу. GlobalFetch['fetch']
- это тип, а не переменная.
Вы имеете в виду импорт node-fetch, а затем преобразование его в GlobalFetch['fetch']
?
Для меня это не вариант, поскольку в моих проектах включен noImplictAny
поэтому я не могу импортировать ничего, что не имеет определения.
Это просто обходной путь, который у меня работает 🤷♀️, но я понимаю, что он далек от совершенства (ключевое слово: _workaround_).
Я думаю, что хорошим решением было бы просто изменить типирование на объединение GlobalFetch['fetch']
и тип экспорта по умолчанию для выборки узлов.
Или просто измените рекомендованную библиотеку на библиотеку для выборки узлов, которая ДЕЙСТВИТЕЛЬНО соответствует GlobalFetch['fetch']
(whatwg-fetch или что-то еще).
Ах, я не понимал, что это было необходимо. TIL.
Извини, у меня действительно выходной. Вы правы, это тип, а не переменная.
https://www.npmjs.com/package/whatwg-fetch довольно четко заявляет, что «Этот проект не работает в средах Node.js. Он предназначен только для веб-браузеров. Вы должны убедиться, что ваше приложение не пытается package и запустите его на сервере ".
Да, кто-то действительно должен исправить ошибку, исправив типы.
При дальнейшем рассмотрении выяснилось, что это в основном проблема с node-fetch
, поэтому я открыл вышеупомянутую проблему. Однако вполне возможно, что они скажут нам просто изменить наши типы.
Хорошо, кажется, node-fetch
говорит нам просто изменить наши типы. Один из способов взлома - импортировать типы node-fetch
и добавить это в качестве обходного пути?
@grantwwu Извините, с описанием GraphQL Summit все довольно беспокойно, но недавно мы начали использовать пакет apollo-env
, который реэкспортирует node-fetch
с правильными типами: https: // github .com / apollographql / apollo-инструменты / дерево / мастер / пакеты / apollo-env
(Мы, вероятно, захотим отделить глобальный экспорт выборки)
Я только что выполнил import { fetch } from 'apollo-env'
и все еще _ получаю ошибки TypeScript при передаче его в конструктор HttpLink
.
TSError: ⨯ Unable to compile TypeScript:
src/index.ts(20,31): error TS2345: Argument of type '{ uri: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; }' is not assignable to parameter of type 'Options'.
Types of property 'fetch' are incompatible.
Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
Types of parameters 'input' and 'input' are incompatible.
Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
Type 'Request' is not assignable to type 'string | Request | undefined'.
Type 'Request' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Request'.
Types of property 'headers' are incompatible.
Type 'Headers' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Headers'.
Types of property 'values' are incompatible.
Type '() => IterableIterator<string>' is not assignable to type '() => Iterator<[string]>'.
Type 'IterableIterator<string>' is not assignable to type 'Iterator<[string]>'.
Types of property 'next' are incompatible.
Type '{ (value?: any): IteratorResult<string>; (value?: any): IteratorResult<string>; }' is not assignable to type '{ (value?: any): IteratorResult<[string]>; (value?: any): IteratorResult<[string]>; }'.
Type 'IteratorResult<string>' is not assignable to type 'IteratorResult<[string]>'.
Type 'string' is not assignable to type '[string]'.
Мне удалось заставить это работать в моем тесте:
import { fetch } from 'apollo-env'
......
function httpLink({ apiUrl, idToken }) {
return new HttpLink({
uri: apiUrl,
headers: {
authorization: `Bearer ${idToken}`,
},
fetch
})
}
У меня все еще не работает: /
src/remoteSchemas.ts:54:45 - error TS2322: Type '(input?: RequestInfo, init?: RequestInit) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit) => Promise<Response>'.
Types of parameters 'input' and 'input' are incompatible.
Type 'RequestInfo' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").RequestInfo'.
Type 'Request' is not assignable to type 'RequestInfo'.
Type 'Request' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").Request'.
Types of property 'headers' are incompatible.
Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]
54 let link = createHttpLink({ uri: url, fetch, fetchOptions: { timeout: remoteSchemaTimeout } });
@jacobtani, какие версии apollo-http-link и apollo-env вы использовали? Кроме того, это с узлом, верно?
Да, здесь то же самое. Использование apollo-env для меня не решает проблему.
Argument of type '{ credentials: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; uri: string; }' is not assignable to parameter of type 'PresetConfig'.
Types of property 'fetch' are incompatible.
Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
Types of parameters 'input' and 'input' are incompatible.
Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
Type 'Request' is not assignable to type 'string | Request | undefined'.
Type 'Request' is not assignable to type 'import("/Users/rahul/work/r3pi/vi-image-contours/node_modules/apollo-env/lib/fetch/fetch").Request'.
Types of property 'headers' are incompatible.
Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]
@grantwwu : я использую
"apollo-client": "^ 2.4.12",
"apollo-env": "^ 0.3.2",
"apollo-link-http": "^ 1.5.9",
Я использую пряжу для управления зависимостями в своем приложении
Я перешел на graphql-запрос для своего проекта.
@jacobtani Как выглядит ваш tsconfig?
apollo-env
по-прежнему отличается от того, что ожидает HttpLink. входной параметр не требуется
Я закончил тем, что переопределил это, и это сработало
declare module "apollo-env" {
export function fetch(
input: RequestInfo,
init?: RequestInit,
): Promise<Response>;
}
Я использую это из узла, используя это
"apollo-env": "^0.3.3"
"apollo-link-http": "^1.5.11"
ПОЖАЛУЙСТА, ЗАПИШИТЕ КОМАНДУ DOCS APOLLO! Этому выпуску больше года
@rlancer Я предполагаю, что это так, потому что, как упоминалось выше в вашем комментарии, он еще не исправлен, поскольку apollo-env
нуждается в патче. Этого нет в этом репо, а в репозитории apollo-tooling
.
@JoviDeCroock Существуют решения, которые работают, в документах должно быть указано, что их следует использовать, в отличие от того, которое дает сбой и заставляет людей искать обходные пути в Google.
@JoviDeCroock и apollo-env
и apollo-tooling
имеют одинаковое объявление типов выборки, и оба они отличаются от Global ['fetch'], ожидаемого HttpLink. Но это не похоже на проблему, если я сам объявляю модуль с тем же объявлением, что и apollo-env
он не жалуется на типы. Может экспорт не работает
Что ж, лично я этим никогда не пользуюсь. Если вы можете указать мне решение, я с удовольствием
Я думаю, что если сделать эти два типа одинаковыми, это должно сработать.
declare function fetch(
input?: RequestInfo, ---> remove ?
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}
@jmca Спасибо, чувак, ты спас мне день, получил удар головой получил проблему Я не определен в новом createUploadLink при использовании шутливого тестирования.
@tafelito Спасибо за ваше решение, оно было очень полезно, но я думаю, что настоящая ошибка была обнаружена, и это связано с новым обновлением TypeScript. В версии 3.6 GlobalFetch
удаляется и вместо него используется WindowOrWorkerGlobalScope
, поэтому это заставляет нас закрыть версию в наших зависимостях package.json "typescript": "3.5.1"
.
Вот ссылка
Чтобы повторить приведенный выше комментарий, мое репо должно придерживаться машинописного текста v3.5.3
Я думаю, что если сделать эти два типа одинаковыми, это должно сработать.
declare function fetch( input?: RequestInfo, ---> remove ? init?: RequestInit ): Promise<Response>; declare interface GlobalFetch { fetch(input: RequestInfo, init?: RequestInit): Promise<Response>; }
Мне удалось исправить это, используя только вторую часть, спасибо @tafelito
та же проблема.
"@types/node-fetch": "^2.5.0",
"typescript": "^3.5.1"
"node-fetch": "^2.6.0",
error TS2345: Argument of type '{ uri: string; fetch: typeof fetch; }' is not assignable to parameter of type 'Options'.
Types of property 'fetch' are incompatible.
Type 'typeof fetch' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
Types of parameters 'url' and 'input' are incompatible.
Type 'RequestInfo' is not assignable to type 'import("/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/@types/node-fetch/index").RequestInfo'.
Type 'Request' is not assignable to type 'RequestInfo'.
Type 'Request' is missing the following properties from type 'Request': context, compress, counter, follow, and 6 more.
8 const link = new HttpLink({ uri: 'http://localhost:3000', fetch });
У меня такая же проблема в моем приложении. Я решаю приведение к any
вот так:
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-boost'
import { createHttpLink } from 'apollo-link-http'
import fetch from 'node-fetch'
const httpLink = createHttpLink({
//ISSUE: https://github.com/apollographql/apollo-link/issues/513
fetch: fetch as any,
uri: 'https://api.graph.cool/simple/v1/swapi',
})
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
})
export default client
в конечном итоге проблема в том, что node-fetch
& связанные типы намеренно отклоняются от спецификации:
// copied directly from the @types/node-fetch
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node-fetch/index.d.ts
Request {
...
// node-fetch extensions to the whatwg/fetch spec
agent?: Agent | ((parsedUrl: URL) => Agent);
compress: boolean;
counter: number;
follow: number;
hostname: string;
port?: number;
protocol: string;
size: number;
timeout: number;
поэтому ошибки компилятора неизбежны, если вы не уменьшите или не создадите новые типы, которые опускают эти дополнения.
я выбрал понижающее значение node-fetch
:
import nodeFetch from 'node-fetch'
import { WhatWgFetch } from '../src/interfaces' // export type WhatWgFetch = typeof fetch
const fetch = (nodeFetch as unknown) as WhatWgFetch
это не здорово, но node-fetch! = fetch, который ... ворчит ... вводит в заблуждение. node-fetch-like
возможно, был бы более подходящим, и оставление расширений _out_ в базовой реализации node-fetch для обеспечения соответствия node-fetch сделало бы одолжение таким, как мы :)
Это могло быть совершенно неуместно ... но ... была такая же проблема в последний день или около того ... только для того, чтобы понять, что "выборка" - это то, что доступно в браузере, но не на стороне сервера. Если ваше приложение будет выполнять выборку из браузера, бессмысленно предварительно визуализировать соединение на стороне сервера.
В моем случае, используя NextJS, я изменил компонент, которому необходимо, чтобы http-ссылка не отображалась на стороне сервера согласно https://nextjs.org/docs#with -no-ssr
У меня была та же проблема, вместо установки node-fetch
и @types/node-fetch
я сразу пошел с apollo-env
и бац! все ошибки ушли!
Мне удалось заставить это работать с изоморфной выборкой
"apollo-link": "1.2.3",
"apollo-link-context": "1.0.9",
"apollo-link-http": "1.3.1",
"aws-appsync": "^3.0.2",
"isomorphic-fetch": "^2.2.1",
...
"@types/isomorphic-fetch": "0.0.35",
declare function fetch(
input?: RequestInfo,
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": [ "dom", "es6", "esnext.asynciterable" ]
...
},
"types": [ "node", "aws-sdk" ],
"include": [ "./src/**/*.ts" ],
...
import * as fetch from 'isomorphic-fetch';
const client = new AWSAppSyncClient(appSyncClientOptions, {
link: createAppSyncLink({
...appSyncClientOptions,
resultsFetcherLink: ApolloLink.from([
createHttpLink({
fetch: fetch as GlobalFetch['fetch'],
uri: appSyncClientOptions.url
})
])
})
});
cross-fetch
!Это работает с машинописным текстом и узлом (не с браузером).
import fetch from 'cross-fetch'
const httpLink = new HttpLink({
uri: "<your-uri>",
fetch,
})
Самый полезный комментарий
(Продолжение от 7 мая 2018 г .:
cross-fetch
теперь поставляется с определениями типов TypeScript)cross-fetch
еще не поставляется с определениями типов TypeScript (как и @DefinitiTyped).Ожидая объединения lquixada / cross-fetch # 12,cross-fetch
- альтернатива, я обнаружил, чтоisomorphic-fetch
работает нормально сHttpLink
в TypeScript на данный момент: