Skip to content

TypeScript: getUserPlaylists() ignores options when userId is undefined #181

Open
@laurence-myers

Description

@laurence-myers

In TypeScript, when calling getUserPlaylists(), the options object is ignored when userId is passed as undefined.

const result = await spotify.getUserPlaylists(undefined, { limit: 50 });
console.log(result.length); // <-- 20, the default limit

This is because the method getUserPlaylists() has dynamic behaviour, re-assigning its arguments if the first argument is not a string. The current types for getUserPlaylists() don't reflect this beahviour.

Code in question:

  Constr.prototype.getUserPlaylists = function (userId, options, callback) {
    var requestData;
    if (typeof userId === 'string') {
      requestData = {
        url: _baseUri + '/users/' + encodeURIComponent(userId) + '/playlists'
      };
    } else {
      requestData = {
        url: _baseUri + '/me/playlists'
      };
      callback = options;
      options = userId;
    }
    return _checkParamsAndPerformRequest(requestData, options, callback);
  };

Types:

getUserPlaylists(
      userId?: string,
      options?: Object,
      callback?: ResultsCallback<SpotifyApi.ListOfUsersPlaylistsResponse>
    ): Promise<SpotifyApi.ListOfUsersPlaylistsResponse>;

Possible fix

You could fix the types by overloading the function signature.

getUserPlaylists(
      options?: Object,
      callback?: ResultsCallback<SpotifyApi.ListOfUsersPlaylistsResponse>
    ): Promise<SpotifyApi.ListOfUsersPlaylistsResponse>;
getUserPlaylists(
      userId: string,
      options?: Object,
      callback?: ResultsCallback<SpotifyApi.ListOfUsersPlaylistsResponse>
    ): Promise<SpotifyApi.ListOfUsersPlaylistsResponse>;

You could also make the types more accurate by using an interface instead of the catch-all Object type for the options, and distinguishing between the Promise-returning and callback versions of the method.

interface PageOptions {
  limit?: number;
  offset?: number;
}

getUserPlaylists(
      options?: PageOptions,
    ): Promise<SpotifyApi.ListOfUsersPlaylistsResponse>;
getUserPlaylists(
      options: PageOptions | undefined,
      callback: ResultsCallback<SpotifyApi.ListOfUsersPlaylistsResponse>
    ): void;
getUserPlaylists(
      userId: string,
      options?: PageOptions,
    ): Promise<SpotifyApi.ListOfUsersPlaylistsResponse>;
getUserPlaylists(
      userId: string,
      options: PageOptions | undefined,
      callback: ResultsCallback<SpotifyApi.ListOfUsersPlaylistsResponse>
    ): void;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions