Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't pass URL class object to fetch() in TypeScript #1695

Closed
Maxim-Mazurok opened this issue Jan 4, 2023 · 3 comments
Closed

Can't pass URL class object to fetch() in TypeScript #1695

Maxim-Mazurok opened this issue Jan 4, 2023 · 3 comments
Labels

Comments

@Maxim-Mazurok
Copy link
Contributor

Reproduction

Steps to reproduce the behavior:

  1. Write fetch(new URL(""));
  2. tsc --noEmit
  3. Observe Argument of type 'URL' is not assignable to parameter of type 'RequestInfo'.ts(2345)

Expected behavior

Works as per example in README: https://github.com/node-fetch/node-fetch#manual-redirect

Screenshots

image

Your Environment

software version
node-fetch 3.3.0
node 19.3.0
npm 9.2.0
typescript 4.9.4
Operating System Windows

Additional context

Related:
#372
nodejs/node#17365
#1430

@jimmywarting
Copy link
Collaborator

According to the spec I couldn't find anything related to that the input should specifically accept a URL class.
image

https://fetch.spec.whatwg.org/#request-class


I would also like to pass URL to fetch/request but i genuinely feel like this is a typescript issue then anything else.

You see some of this web api's have WebIDL conversion that normalize parameters to what it would like to have as an input parameter.

ref: https://www.npmjs.com/package/webidl-conversions

So you can (if you like to) just simply pass in an object, number, boolean, or literally anything you want. and WebIDL will try it's best to convert whatever you throw at it into a string.

fetch({
  toString() {
    return 'https://httpbin.org/get'
  }
}) // will fetch https://httpbin.org/get
fetch(true) // will fetch `./true`
fetch((blogId = 2)) // will fetch `./2`
fetch({}) // // will fetch `./[object%20Object]`
fetch({
  [Symbol.toPrimitive](hint) {
    console.log(hint)
    if (hint === 'string') {
      return 'https://httpbin.org/image/png'
    }
    return null
  }
}) // will fetch https://httpbin.org/image/png and log the hint: 'string'

And the URL class just so happens to have a URL.prototype.toString method that makes it work as you would like it to do.

So do i feel like we should add in each and every method like URL, boolean, number, bigint, toString and toPrimitive and so on? no
Do i think this is a typescript issue? yes, TS isn't so good for a loosed typed language.
If anything i think it should be

/**
 * @param { Request | any } input
 * @param { RequestInit } init
 */  
function fetch(input, init) { ... }

Something even better would be to use USVString

/**
 * @param { Request | USVString } input
 * @param { RequestInit } init
 */  
function fetch(input, init) { ... }

but TS don't have any logic about USVString and how it can convert whatever into a USVString (it only have string support)

it's the same argument about URLSearchParams not supporting numbers and booleans: microsoft/TypeScript-DOM-lib-generator#1568

TS should actually have some kind of stringable USVString logic that we can use for ppl who mostly write polyfills microsoft/TypeScript#28775

@LinusU
Copy link
Member

LinusU commented Jan 4, 2023

Duplicate of microsoft/TypeScript#1261?

But yeah, this is a though one. There is no special handling of Url in the spec, but it is a common use case.

TypeScript DOM typings does allow URL specifically:

https://github.com/microsoft/TypeScript/blob/f43cd0accac3e5033820fd27035731ed88f54938/lib/lib.dom.d.ts#L18281

@Maxim-Mazurok
Copy link
Contributor Author

Thanks for your input guys, I believe this is a duplicate of microsoft/TypeScript#1261 indeed, so I'll reply in there, cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants