googleapis / nodejs-tasks

This repository is deprecated. All of its content and history has been moved to googleapis/google-cloud-node.
https://cloud.google.com/tasks/docs/
Apache License 2.0
142 stars 45 forks source link

Create Task type warning about `httpMethod` being invalid #637

Closed MorenoMdz closed 2 years ago

MorenoMdz commented 2 years ago

Environment details

Steps to reproduce

  1. Declare the tasks object as following:
    const task = {
      httpRequest: {
        httpMethod: "POST",
        url: functionUrl,
        oidcToken: {
          serviceAccountEmail,
          audience: new URL(functionUrl).origin
        },
        headers: {
          "Content-Type": "application/json",
          ...headers
        },
        retryConfig: {
          max_attempts: 16,
          min_backoff: 2 // in seconds
        },
        body
      },
      scheduleTime: { seconds: targetTimeInSeconds }
    };

Typescript will complain at the taskClient.createTask(request)

Argument of type '{ parent: string; task: { httpRequest: { httpMethod: string; url: string; oidcToken: { serviceAccountEmail: any; audience: string; }; headers: any; retryConfig: { max_attempts: number; min_backoff: number; }; body: string; }; scheduleTime: { ...; }; }; }' is not assignable to parameter of type 'ICreateTaskRequest'. The types of 'task.httpRequest.httpMethod' are incompatible between these types. Type 'string' is not assignable to type '"POST" | HttpMethod | "HTTP_METHOD_UNSPECIFIED" | "GET" | "HEAD" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | null | undefined'.ts(2345)

But if we rename httpMethod to http_method it passes, but I is probably ignoring this field and defaulting to POST anyway.

Expected

Types should properly recognize the task data, documentation should provide more examples for those fields.

alexander-fenster commented 2 years ago

Copy-pasting my response from #331:

This is not the library problem, but the problem with how TypeScript guesses the type of the httpRequest field. Since you have const task = { httpRequest: 'POST' }, TypeScript decides that the type of the task variable is { httpRequest: string }, which cannot be be used in the API request because it expects { httpRequest: 'POST' | 'GET' | ... }. We could've solved this by making the parameter accept any string instead of keyof typeof ..., but then we would've lost all compile time checks for the string enum values.

You can do the following to tell TypeScript compiler that the type of the task is ITask:

import {CloudTasksClient, protos} from '@google-cloud/tasks';

...

    const task: protos.google.cloud.tasks.v2.ITask = {
      appEngineHttpRequest: {
        httpMethod: 'POST',
        relativeUri: '/log_payload',
      },
    };

and then it will understand that httpRequest is of type 'POST' | 'GET' | ... and will happily pass it to the API.

Since our samples are in JavaScript and not in TypeScript, sometimes (in cases like this one) they cannot be easily copy-pasted to the TypeScript code. I took samples/quickstart.js and made it compile in TypeScript by adding type information here and there: gist

I hope that helps!

As for the documentation question: unfortunately, at this moment we don't provide TypeScript samples, only JavaScript (even though the library itself is in TypeScript).