import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = new HttpLink({
fetch,
uri: this.endPoint.toString(),
Intended outcome:
According to the documentation the above should have compiled.
Actual outcome:
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);
How to reproduce the issue:
Following versions are used to write above code.
"@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"
Use the above versions and create the instance of HttpLink in typescript to see the above error.
huan, Type1J, NattapongSiri, BrunoScheufler, jorroll, Kocal, zhuang1992, leebenson, lostfictions, kjjgibson, and 32 more reacted with thumbs up emoji
dearsaturn, jtushman, SCollinA, and ajhool reacted with confused emoji
All reactions
What happens if you use createHttpLink
instead of new HttpLink
?
import { createHttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = createHttpLink({
fetch,
uri: this.endPoint.toString(),
The node-fetch 2.x is not compatible with apollo-link. The signature of fetch is different.
Ah, I guess you can duck punch it.
I came across this issue today in my isomorphic app. I don't totally agree with global fetch being the default fallback especially in these days of SSR, but at least the error was somewhat informative:
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';
My solution was either to conditionally usenode-fetch
or whatwg-fetch
depending on the node/browser environment. Or just use cross-fetch
which basically does the same thing.
So...
// Using TypeScript
import * as fetch from 'cross-fetch'
new HttpLink({ fetch })
// Or just...
// import 'cross-fetch/polyfill'
I ran into this issue today, and find out we are not compatible with node-fetch
v2, I believe we should fix this.
I start using cross-fetch
now but it just imports a fetch: any
...
(Follow up on May 7, 2018: cross-fetch
now comes with TypeScript type definitions)
cross-fetch
has not shipped with TypeScript type definitions yet (nor does @DefinitelyTyped).
While waiting for lquixada/cross-fetch#12 to be merged cross-fetch
is an alternative, I found isomorphic-fetch
working alright with HttpLink
in TypeScript as of now:
import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'
const link = new HttpLink({
fetch
huan, topdiary, BrunoScheufler, jaaaco, zephyrpersonal, sandiiarov, kalch, GromNaN, neyron163, dicrescenzoa, and 7 more reacted with thumbs up emoji
marcellobarile, kalch, donedgardo, jvmonjo, and GromNaN reacted with heart emoji
All reactions
The npmjs.com documentation encourages users to use node-fetch but doesn't specify which version. How can we update that documentation?
Note: using whatwg-fetch
is a viable workaround.
Has there been any movement on this?
Using cross-fetch
seems like a strange workaround since it just uses node-fetch
. Is that not actually a problem?
whatwg-fetch
is not a workaround for those of us on the server side.
using HttpLink is optional, this works for me:
import ApolloClient from 'apollo-boost'
import 'isomorphic-fetch'
const client = new ApolloClient({
uri: 'endpoint-url-here'
dberringer, crapthings, dshook, ralphilius, jvmonjo, piecioshka, snettah, wenderjean, and rena0531 reacted with thumbs up emoji
ralphilius and piecioshka reacted with hooray emoji
piecioshka reacted with rocket emoji
All reactions
A workaround for this is to not install @types/node-fetch
and manually define it as GlobalFetch yourself.
To do this, add the following to any .d.ts
file in your project;
// 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;
Sure but what is the point of installing the types at all, if you're just gonna force cast it to something else eitherway?
Might as well use my solution in that case.
Sorry, I misread what you were doing, ignore my previous comment.
However, this requires you modify your tsconfig to target the browser, as GlobalFetch is only provided if you have "dom" as an entry in the "lib" field: #273 (comment)
Secondly, instead of manually modifying a .d.ts
, couldn't you just pass GlobalFetch['fetch']
to the HTTPLink constructor? That makes it a lot less hidden.
Sure, but to conform to HttpLink's typing you have to use GlobalFetch['fetch']
regardless so I see no way around that requirement.
I don't follow. GlobalFetch['fetch']
is a type, not a variable.
Do you mean importing node-fetch and then casting it to GlobalFetch['fetch']
?
That's not on option for me as I have noImplictAny
enabled in my projects so I can't import anything that doesn't have a definition.
It's just a workaround that works for me 🤷♀️, but I realise it's far from perfect (keyword: workaround).
I think a good solution would be to just change the typing to a union of GlobalFetch['fetch']
and the default type of node-fetch's export.
Or just change the recommended library to a node fetch lib that DOES conform to GlobalFetch['fetch']
(whatwg-fetch or whatever).
https://www.npmjs.com/package/whatwg-fetch states pretty explicitly that "This project doesn't work under Node.js environments. It's meant for web browsers only. You should ensure that your application doesn't try to package and run this on the server."
Yes, someone really ought to fix the bug properly by fixing the types.
I've just done an import { fetch } from 'apollo-env'
and I'm still getting TypeScript errors when passing it into the HttpLink
constructor.
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]'.
It's still not working for me :/
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 which versions of apollo-http-link and apollo-env did you use? Also, this is with node, right?
Yes, same here. Using apollo-env does not solve the issue for me.
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]
apollo-env
is still different from what HttpLink expects. the input param should not be required
I ended up overriding it like this and it worked
declare module "apollo-env" {
export function fetch(
input: RequestInfo,
init?: RequestInit,
): Promise<Response>;
I'm using this from node using this
"apollo-env": "^0.3.3"
"apollo-link-http": "^1.5.11"
@JoviDeCroock both apollo-env
and apollo-tooling
has the same fetch types declaration and both are different from the Global['fetch'] that the HttpLink expects. But this doesn't seem to be the problem, if I declare the module myself with the same declaration as apollo-env
it does not complain about types. Maybe the export is not working
I guess by making these 2 types the same should work.
declare function fetch(
input?: RequestInfo, ---> remove ?
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
@tafelito Thanks for your solution, it was very helpful, but I think the real error was found and it is due to the new TypeScript update. In its 3.6 version, GlobalFetch
is removed and WindowOrWorkerGlobalScope
is used instead, so this forces us to close the version in our dependencies of the package.json "typescript": "3.5.1"
.
Here is the link
I guess by making these 2 types the same should work.
declare function fetch(
input?: RequestInfo, ---> remove ?
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
I've been able to fix it using only the second part, thanks @tafelito
"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 });
I have same problem in my application. I solve casting to any
like that:
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
ultimately the problem is that the node-fetch
& associated typings intentionally deviate from the spec:
// 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;
so compiler errors are inevitable if you don't downcast or create new typings that omit these additions.
i chose to downcast node-fetch
:
import nodeFetch from 'node-fetch'
import { WhatWgFetch } from '../src/interfaces' // export type WhatWgFetch = typeof fetch
const fetch = (nodeFetch as unknown) as WhatWgFetch
it's not great, but node-fetch != fetch, which ...grumbles... is misleading. node-fetch-like
may have been more appropriate, and leaving the extensions out in the base node-fetch implementation to keep node-fetch compliant would have done the likes of us a favor :)
This might be completely irrelevant ... but ... had the same issue for the last day or so...only to realize that 'fetch' is something that is available in the browser, but not on the server-side. If your application is going to be doing fetching from the browser, it's kind of pointless to pre-render the connection on the server-side.
In my case, using NextJS, I changed the component that needed the http-link to not be rendered on the server-side as per https://nextjs.org/docs#with-no-ssr
I managed to get this working with isomorphic-fetch
package.json (all version selected for compatibility with that used by appsync)
"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",
.../typings/index.d.ts
declare function fetch(
input?: RequestInfo,
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
tsconfig.json
"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
Consider cross-fetch
!
This works with typescript and node(not browser).
import fetch from 'cross-fetch'
const httpLink = new HttpLink({
uri: "<your-uri>",
fetch,
`node-fetch` types aren't fully compatible with AC3, leading to
TS compiler errors in some cases (for the full backstory, see
apollographql/apollo-link#513).
`cross-fetch` addresses these type issues (while still using
`node-fetch` under the hood), and also supports older browsers
as well. This means we can recommend the use of `cross-fetch`
instead of both `unfetch` and `node-fetch`. This PR updates our
docs and code checks accordingly.
The `node-fetch` types aren't fully compatible with AC3, leading to
TS compiler errors in some cases (for the full backstory, see
apollographql/apollo-link#513).
`cross-fetch` addresses these type issues (while still using
`node-fetch` under the hood), and also supports older browsers
as well. This means we can recommend the use of `cross-fetch`
instead of both `unfetch` and `node-fetch`. This PR updates our
docs and code checks accordingly.