Skip to content

encodeURIComponent should accept any value type #18159

Closed
@2is10

Description

@2is10

TypeScript Version: 2.5.2

Code

encodeURIComponent(true);

Expected behavior:
tsc compiles with no errors.

Actual behavior:
error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'.

Discussion:

encodeURIComponent is currently defined liked this:

declare function encodeURIComponent(uriComponent: string): string; 

In reality, encodeURIComponent accepts any value and coerces it to a string if necessary. The first step in its definition in the ES6 spec reads:

  1. Let componentString be ToString(uriComponent).

It’s pretty common to pass true or false or a number like 0 or 10 as a query parameter, for instance. Here are two possible ways to broaden the definition:

declare function encodeURIComponent(uriComponent: any): string; 

declare function encodeURIComponent(uriComponent: string | number | boolean): string; 

The any option would be technically correct, but passing null or undefined or a non-primitive value is usually a bug (in my experience). You can use your own judgment about how broadly the uriComponent argument should be defined. I’m specifically interested in using number and boolean.

Activity

mhegazy

mhegazy commented on Aug 30, 2017

@mhegazy
Contributor

Similar discussion can be found in #4002.

We have chosen to be more strict with the standard library and only allow strings, not things that can be coerced into string by the engine.

added
Working as IntendedThe behavior described is the intended behavior; this is not a bug
on Aug 30, 2017
rattrayalex-stripe

rattrayalex-stripe commented on Aug 30, 2017

@rattrayalex-stripe

I think this is different than #4002, since it explicitly/transparently does coercion for the return value, not merely for a comparison value.

I probably never intend to do isFinite(someBoolean), but I could intend to use encodeURIComponent(someBoolean) as a shorthand for encodeURIComponent(someBoolean.toString()) since it has the same effect

added
Domain: lib.d.tsThe issue relates to the different libraries shipped with TypeScript
SuggestionAn idea for TypeScript
and removed
Working as IntendedThe behavior described is the intended behavior; this is not a bug
on Aug 30, 2017
mhegazy

mhegazy commented on Aug 30, 2017

@mhegazy
Contributor

Would take a PR for it.

neoncube2

neoncube2 commented on Nov 23, 2017

@neoncube2

I just ran into this when trying to encode numbers, too.

Doing something like the below code gives a compile-time error, which, as someone more used to plain JavaScript, was unexpected.

getUrl(column: number) { return 'http://example.com/' + encodeUriComponent(column); }

added this to the Community milestone on Jan 4, 2018
jdalrymple

jdalrymple commented on Nov 12, 2018

@jdalrymple

Is there a way to override the declaration in the mean time?

jdalrymple

jdalrymple commented on Nov 12, 2018

@jdalrymple

Figured it out:

declare global {
  function encodeURIComponent(uriComponent: string | number | boolean): string; 
}
NN---

NN--- commented on Feb 12, 2019

@NN---

@jdalrymple Do you have time to submit PR , please ?

smockle

smockle commented on Apr 24, 2019

@smockle
Member

Opened PR #31103

From this issue’s description:

It’s pretty common to pass true or false or a number like 0 or 10 as a query parameter, for instance. Here are two possible ways to broaden the definition:

declare function encodeURIComponent(uriComponent: any): string; 
declare function encodeURIComponent(uriComponent: string | number | boolean): string; 

The any option would be technically correct, but passing null or undefined or a non-primitive value is usually a bug (in my experience). You can use your own judgment about how broadly the uriComponent argument should be defined. I’m specifically interested in using number and boolean.

I opted for the first solution (using any) because it more closely matches the ES5 spec, but I see merit in @2is10’s second solution as well.

added a commit that references this issue on Apr 26, 2019
d934401
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @NN---@2is10@smockle@jdalrymple@RyanCavanaugh

      Issue actions

        encodeURIComponent should accept any value type · Issue #18159 · microsoft/TypeScript