Menggunakan HttpLink dengan pengambilan simpul memberikan kesalahan berikut:
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = new HttpLink({
fetch,
uri: this.endPoint.toString(),
});
Hasil yang diinginkan:
Menurut dokumentasi di atas seharusnya sudah dikompilasi.
Hasil sebenarnya:
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);
Cara mereproduksi masalah:
Versi berikut digunakan untuk menulis kode di atas.
"@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"
Gunakan versi di atas dan buat instance HttpLink di TypeScript untuk melihat kesalahan di atas.
Apa yang terjadi jika Anda menggunakan createHttpLink
alih-alih new HttpLink
?
import { createHttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = createHttpLink({
fetch,
uri: this.endPoint.toString(),
});
@dejayc Ini memberikan kesalahan yang sama ketika createHttpLink digunakan.
Sebenarnya, saya menemukan masalahnya. Node-fetch 2.x tidak kompatibel dengan _apollo-link_. Tanda tangan _fetch_ berbeda.
Node-fetch 2.x tidak kompatibel dengan apollo-link. Tanda tangan dari fetch berbeda.
Ah, saya kira Anda bisa meninju bebek itu.
Saya menemukan masalah ini hari ini di aplikasi isomorfik saya. Saya tidak sepenuhnya setuju dengan pengambilan global sebagai fallback default terutama pada hari-hari SSR ini, tetapi setidaknya kesalahannya agak informatif:
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';
Solusi saya adalah menggunakan node-fetch
secara kondisional atau whatwg-fetch
tergantung pada lingkungan node/browser. Atau cukup gunakan cross-fetch
yang pada dasarnya melakukan hal yang sama.
Jadi...
// Using TypeScript
import * as fetch from 'cross-fetch'
new HttpLink({ fetch })
// Or just...
// import 'cross-fetch/polyfill'
@jmca Cara yang Anda sarankan untuk TypeScript berhasil untuk saya! Terima kasih!!
Saya mengalami masalah ini hari ini, dan mengetahui bahwa kami tidak kompatibel dengan node-fetch
v2, saya yakin kami harus memperbaikinya.
Saya mulai menggunakan cross-fetch
sekarang tetapi hanya mengimpor fetch: any
...
(Tindak lanjut pada 7 Mei 2018: cross-fetch
kini hadir dengan definisi tipe TypeScript)
cross-fetch
belum dikirimkan dengan definisi tipe TypeScript (juga @DefinitelyTyped).
Sambil menunggu lquixada/cross-fetch#12 digabungkan cross-fetch
adalah alternatif, saya menemukan isomorphic-fetch
bekerja dengan baik dengan HttpLink
di TypeScript seperti sekarang:
import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'
const link = new HttpLink({
fetch
})
Dokumentasi npmjs.com mendorong pengguna untuk menggunakan pengambilan simpul tetapi tidak menentukan versi mana. Bagaimana kami dapat memperbarui dokumentasi itu?
Catatan: menggunakan whatwg-fetch
adalah solusi yang layak.
Apakah ada gerakan dalam hal ini?
Menggunakan cross-fetch
sepertinya solusi yang aneh karena hanya menggunakan node-fetch
. Bukankah itu sebenarnya masalah?
whatwg-fetch
bukan solusi bagi kita di sisi server.
Jika seseorang membuka PR yang menyertakan definisi tipe yang tepat yang akan berfungsi dengan semua implementasi pengambilan tetapi mempertahankan beberapa pemeriksaan tipe, tolong @stubailo saya dan saya akan mencoba menggabungkannya!
@stubailo Pada Apollo Server kami menggunakan ini sebagai bagian dari apollo-server-env
.
menggunakan HttpLink adalah opsional, ini berfungsi untuk saya:
import ApolloClient from 'apollo-boost'
import 'isomorphic-fetch'
const client = new ApolloClient({
uri: 'endpoint-url-here'
})
Ada berita tentang ini? node-fetch masih menyebabkan masalah dengan apollo-link dan TS.
Ada berita? Masih mendapatkan masalah dengan node-fetch
Solusi untuk ini adalah tidak menginstal @types/node-fetch
dan secara manual mendefinisikannya sebagai GlobalFetch sendiri.
Untuk melakukannya, tambahkan yang berikut ini ke file .d.ts
di proyek Anda;
// 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;
}
Anda bisa menggunakan hal paksaan jenis as
...
Tentu, tetapi apa gunanya menginstal tipe sama sekali, jika Anda hanya akan memaksanya untuk melemparkannya ke sesuatu yang lain?
Mungkin juga menggunakan solusi saya dalam kasus itu.
Maaf, saya salah membaca apa yang Anda lakukan, abaikan komentar saya sebelumnya.
Namun, ini mengharuskan Anda memodifikasi tsconfig Anda untuk menargetkan browser, karena GlobalFetch hanya disediakan jika Anda memiliki "dom" sebagai entri di bidang "lib": https://github.com/apollographql/apollo-link/issues/ 273#issuecomment -347878009
Kedua, daripada memodifikasi secara manual .d.ts
, tidak bisakah Anda meneruskan GlobalFetch['fetch']
ke konstruktor HTTPLink? Itu membuatnya jauh lebih sedikit tersembunyi.
Tentu, tetapi untuk menyesuaikan dengan pengetikan HttpLink Anda harus menggunakan GlobalFetch['fetch']
terlepas dari itu, jadi saya tidak melihat jalan keluar dari persyaratan itu.
Saya tidak mengikuti. GlobalFetch['fetch']
adalah tipe, bukan variabel.
Maksud Anda mengimpor node-fetch dan kemudian mentransmisikannya ke GlobalFetch['fetch']
?
Itu bukan pilihan bagi saya karena saya mengaktifkan noImplictAny
di proyek saya sehingga saya tidak dapat mengimpor apa pun yang tidak memiliki definisi.
Ini hanya solusi yang berhasil untuk saya ️, tetapi saya menyadari itu jauh dari sempurna (kata kunci: _workaround_).
Saya pikir solusi yang baik adalah dengan hanya mengubah pengetikan menjadi gabungan GlobalFetch['fetch']
dan tipe default ekspor pengambilan simpul.
Atau cukup ubah pustaka yang direkomendasikan ke lib pengambilan simpul yang TIDAK sesuai dengan GlobalFetch['fetch']
(whatwg-fetch atau apa pun).
Ah, saya tidak menyadari itu diperlukan. TIL.
Maaf, aku hanya sedang libur. Anda benar, itu tipe, bukan variabel.
https://www.npmjs.com/package/whatwg-fetch menyatakan dengan cukup eksplisit bahwa "Proyek ini tidak bekerja di bawah lingkungan Node.js. Ini dimaksudkan untuk browser web saja. Anda harus memastikan bahwa aplikasi Anda tidak mencoba untuk paket dan jalankan ini di server."
Ya, seseorang benar-benar harus memperbaiki bug dengan benar dengan memperbaiki jenisnya.
Setelah ditinjau lebih lanjut, ini tampaknya terutama merupakan masalah dengan node-fetch
, jadi saya membuka masalah di atas. Sangat mungkin bahwa mereka akan memberitahu kita untuk hanya mengubah tipe kita.
Oke, node-fetch
sepertinya menyuruh kita untuk hanya mengubah tipe kita. Satu peretasan adalah mengimpor tipe node-fetch
dan menambahkannya sebagai solusi?
@grantwwu Maaf, hal-hal yang cukup sibuk dalam ikhtisar ke GraphQL Summit, tetapi kami baru-baru ini mulai menggunakan paket apollo-env
yang mengekspor ulang node-fetch
dengan jenis yang tepat: https://github .com/apollographql/apollo-tooling/tree/master/packages/apollo-env
(Kami mungkin ingin memisahkan ekspor pengambilan global)
Saya baru saja melakukan import { fetch } from 'apollo-env'
dan saya _still_ mendapatkan kesalahan TypeScript saat meneruskannya ke konstruktor 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]'.
Saya berhasil menjalankan ini dalam pengujian saya:
import { fetch } from 'apollo-env'
......
function httpLink({ apiUrl, idToken }) {
return new HttpLink({
uri: apiUrl,
headers: {
authorization: `Bearer ${idToken}`,
},
fetch
})
}
Itu masih tidak bekerja untuk saya :/
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 versi apollo-http-link dan apollo-env mana yang Anda gunakan? Juga, ini dengan node, kan?
Ya, sama di sini. Menggunakan apollo-env tidak menyelesaikan masalah bagi saya.
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 : saya pakai
"apollo-klien": "^2.4.12",
"apollo-env": "^0.3.2",
"apollo-link-http": "^1.5.9",
Saya menggunakan benang untuk manajemen ketergantungan di aplikasi saya
Saya beralih ke graphql-request untuk proyek saya.
@jacobtani Seperti apa tampilan tsconfig Anda?
apollo-env
masih berbeda dari yang diharapkan HttpLink. parameter input seharusnya tidak diperlukan
Saya akhirnya menimpanya seperti ini dan berhasil
declare module "apollo-env" {
export function fetch(
input: RequestInfo,
init?: RequestInit,
): Promise<Response>;
}
Saya menggunakan ini dari simpul menggunakan ini
"apollo-env": "^0.3.3"
"apollo-link-http": "^1.5.11"
HARAP PATCH TIM DOCS APOLLO! Masalah ini sudah lebih dari satu tahun
@rlancer Saya menganggap ini masalahnya karena seperti yang disebutkan di atas komentar Anda, itu belum diperbaiki karena apollo-env
membutuhkan tambalan. Ini bukan di repo ini tetapi di repositori apollo-tooling
.
@JoviDeCroock Ada solusi yang berfungsi, dokumen harus menunjukkan untuk menggunakannya sebagai lawan dari solusi yang gagal dan memaksa orang ke Google untuk mencari solusi.
@JoviDeCroock apollo-env
dan apollo-tooling
memiliki deklarasi tipe pengambilan yang sama dan keduanya berbeda dari Global['fetch'] yang diharapkan oleh HttpLink. Tapi ini sepertinya bukan masalah, jika saya mendeklarasikan modul sendiri dengan deklarasi yang sama dengan apollo-env
itu tidak mengeluh tentang tipe. Mungkin ekspornya tidak berfungsi
Yah, saya pribadi tidak pernah menggunakan ini. Jika Anda dapat mengarahkan saya ke solusi, saya dengan senang hati akan pr
Saya kira dengan membuat 2 jenis ini seharusnya berfungsi.
declare function fetch(
input?: RequestInfo, ---> remove ?
init?: RequestInit
): Promise<Response>;
declare interface GlobalFetch {
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}
@jmca Terima kasih
@tafelito Terima kasih atas solusi Anda, itu sangat membantu, tapi saya pikir kesalahan sebenarnya ditemukan dan itu karena pembaruan TypeScript baru. Dalam versi 3.6, GlobalFetch
dihapus dan WindowOrWorkerGlobalScope
digunakan sebagai gantinya, jadi ini memaksa kita untuk menutup versi di dependensi package.json "typescript": "3.5.1"
.
Ini linknya
Untuk menggemakan komentar di atas, repo saya harus tetap menggunakan TypeScript v3.5.3
Saya kira dengan membuat 2 jenis ini seharusnya berfungsi.
declare function fetch( input?: RequestInfo, ---> remove ? init?: RequestInit ): Promise<Response>; declare interface GlobalFetch { fetch(input: RequestInfo, init?: RequestInit): Promise<Response>; }
Saya sudah bisa memperbaikinya hanya menggunakan bagian kedua, terima kasih @tafelito
masalah yang sama.
"@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 });
Saya memiliki masalah yang sama di aplikasi saya. Saya memecahkan casting ke any
seperti itu:
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
pada akhirnya masalahnya adalah bahwa node-fetch
& pengetikan terkait sengaja menyimpang dari spesifikasi:
// 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;
jadi kesalahan kompiler tidak dapat dihindari jika Anda tidak menurunkan atau membuat pengetikan baru yang menghilangkan penambahan ini.
saya memilih untuk 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
itu tidak bagus, tapi node-fetch != fetch, yang ...menggerutu... menyesatkan. node-fetch-like
mungkin lebih tepat, dan membiarkan ekstensi _out_ dalam implementasi node-fetch dasar agar tetap sesuai dengan node-fetch akan membantu kami :)
Ini mungkin sama sekali tidak relevan ... tetapi ... memiliki masalah yang sama selama beberapa hari terakhir ... hanya untuk menyadari bahwa 'ambil' adalah sesuatu yang tersedia di browser, tetapi tidak di sisi server. Jika aplikasi Anda akan melakukan pengambilan dari browser, tidak ada gunanya melakukan pra-render koneksi di sisi server.
Dalam kasus saya, menggunakan NextJS, saya mengubah komponen yang memerlukan tautan http agar tidak dirender di sisi server sesuai https://nextjs.org/docs#with -no-ssr
Saya mengalami masalah yang sama, alih-alih menginstal node-fetch
dan @types/node-fetch
saya langsung menggunakan apollo-env
dan bam! semua kesalahan hilang!
Saya berhasil membuatnya bekerja dengan isomorphic-fetch
"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
!Ini berfungsi dengan TypeScript dan node (bukan browser).
import fetch from 'cross-fetch'
const httpLink = new HttpLink({
uri: "<your-uri>",
fetch,
})
Komentar yang paling membantu
(Tindak lanjut pada 7 Mei 2018:
cross-fetch
kini hadir dengan definisi tipe TypeScript)cross-fetch
belum dikirimkan dengan definisi tipe TypeScript (juga @DefinitelyTyped).Sambil
menunggu lquixada/cross-fetch#12 digabungkancross-fetch
adalah alternatif, saya menemukanisomorphic-fetch
bekerja dengan baik denganHttpLink
di TypeScript seperti sekarang: