66763


お世話になります。  
Google Apps ScriptでSlackにアクセスするアプリを開発しています。  
claspを使ってTypeScriptで書いています。  
Emacsでtide.elを使って、画面にエラーが表示されるようにしています。  
以下のコードを書きました。

[code]

    function test() {
      let url = 'https://hooks.slack.com/services/xxxxxxxxxx/xxxxxxxxxxxxxxx';
      let params = {
        method: 'post',
        contentType: 'application/json',
        payload: '{"text":"Hello, World!"}'
      };
    
      UrlFetchApp.fetch(url, params);
    }
    
[/code]

すると、最後の

[code]

      UrlFetchApp.fetch(url, params);
    
[/code]

の`params`について、以下のようなエラーが出ました。  
（tide.elおよびtscで両方）

> error TS2345: Argument of type '{ method: string; contentType:> string;
> payload: string; }'  
>  is not assignable to parameter of type 'URLFetchRequestOptions'.  
>  Types of property 'method' are incompatible.  
>  Type 'string' is not assignable to type 'HttpMethod'.

HttpMethodというtypeが、以下のファイルに見つかりました。

node_modules/@types/google-apps-script/google-apps-script.url-fetch.d.ts

この中には、以下のようなコードがありました。

[code]

    declare namespace GoogleAppsScript {
      namespace URL_Fetch {
        /**
         * This class allows users to access specific information on HTTP responses.
         * See also
         *
         * UrlFetchApp
         */
    
    …中略…
    
        interface URLFetchRequestOptions {
    
    …中略…
    
          /**
           * the HTTP method for the request: get, delete, patch, post, or put. The default is get.
           */
          method?: HttpMethod;
    
    …中略…
    
        type HttpMethod = 'get' | 'delete' | 'patch' | 'post' | 'put';
    
[/code]

つまり、`HttpMethod`型に`string`を代入してはいけない、と書いていますが、代入しているのはこの5つの中の`'post'`ですから、合っているような気がします。

分からないなりに、以下のようにgoogle-apps-script.url-fetch.d.tsを改変しました。

[code]

    type HttpMethod = string | 'get' | 'delete' | 'patch' | 'post' | 'put';
    
[/code]

これでエラーはなくなりました。

google-apps-script.url-
fetch.d.tsを改変する前のエラーが出る状態でも、改変したあとのエラーが出ない状態でも、GAS側にpushして実行すると、正しく実行されますが、せっかく間違えた値を書かないようにtype宣言されているのに、気持ち悪い気がします。  
エラーが出ないようにするには、どうすればいいでしょうか？  
よろしくお願いいたします。


CC BY-SA 4.0
2020-05-19T03:34:10.747
66761
2020-05-29T03:20:47.680
2020-05-29T03:20:47.680
26673
26673
question
google-apps-script typescript
TypescriptでGASを書いていると、HttpMethodでerror TS2345が出る

[code]

    let params = {
        method: 'post',
        contentType: 'application/json',
        payload: '{"text":"Hello, World!"}'
      };
    
[/code]

のように、変数定義を書くと、型推論により`params`の型が

[code]

    { method: string; contentType: string; payload: string; }
    
[/code]

になってしまいます。このように型付けされた変数を引数として与える場合の型チェックは、中身の値ではなく、型そのものによって判定されるので、

[code]

    interface URLFetchRequestOptions {
        //...
    
        method?: HttpMethod;
    
        //...
    }
    
[/code]

と言う、`URLFetchRequestOptions`とはマッチしないと判定されます。

* * *

解決のためには、

  * `params`の型を明示的に宣言してやる

[code]

    let params: URLFetchRequestOptions = {
        method: 'post',
        contentType: 'application/json',
        payload: '{"text":"Hello, World!"}'
    };
    
[/code]

  * 変数を使用せずにオブジェクト表記をそのまま書く

[code]

    UrlFetchApp.fetch(url, {
        method: 'post',
        contentType: 'application/json',
        payload: '{"text":"Hello, World!"}'
    });
    
[/code]

と言ったやり方が考えられます。


CC BY-SA 4.0
2020-05-19T04:19:24.563
66763
2020-05-19T04:19:24.563
13972
66761
answer