【问题标题】:Anyone know how to Typescript this, response?任何人都知道如何打字,回应?
【发布时间】:2020-06-29 19:40:54
【问题描述】:

我不知道如何输入:这会产生很多错误。

// This seems all wrong as it just creating more errors
interface Response {
  status: number;
  statusText: string;
  error: Error
}

/*
  // TS7053: Element implicitly has an 'any' type because expression 
    of type '"text" | "json"' can't be used to index type 'Response'.         Property 'text' does not exist on type 'Response'
*/ 
function parseResponse(response) {
  return response[response.status === 204 ? 'text' : 'json']();
}

function checkStatus(response) {
  if (response && response.status >= 200 && response.status < 300) {
    return response;
  }

  const error = new Error(response ? response.statusText : 'Offline');
  error.response = response; // TS2339: Property 'response' does not exist on type 'Error'.
  throw error;
}

我还有其他问题吗?

export default function request(url: string, options = {}) {
  const requestOptions = {
    credentials: 'include',
    headers: {
     Accept: 'application/json',
    },
 };

 const tokenAuth = authToken.getAuthToken();

 if (tokenAuth) {
   requestOptions.headers['Auth-Token'] = tokenAuth;
 }

显示错误:TS7053:元素隐式具有“任何”类型,因为“Auth-Token”类型的表达式不能用于索引类型“{ Accept: string; }'。类型 '{ Accept: string; 上不存在属性 'Auth-Token' }'。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    Response 是一种已在全球范围内存在的类型。您不必全部定义。就用它吧:

    function parseResponse(response: Response) { /* ... */ }
    function checkStatus(response: Response) { /* ... */ }
    

    对于第二个问题,如果您想添加对错误的响应,则默认情况下该属性不存在。您可能希望继承 Error,添加属性,然后实例化该特定错误类。

    class ResponseError extends Error {
        response?: Response
    }
    
    function checkStatus(response: Response) {
      if (response && response.status >= 200 && response.status < 300) {
        return response;
      }
    
      const error = new ResponseError(response ? response.statusText : 'Offline');
      error.response = response;
      throw error;
    }
    

    现在您可以通过首先检查它的类来捕获该错误并访问该属性,因此编译器可以确定它是什么类型的错误,因此存在响应属性:

    // Catch the error
    fetch('/').then(res => {
        try {
            checkStatus(res)
        } catch (err) {
            if (err instanceof ResponseError) {
                // Can access the .response property on err here
                console.error("Error with response:", err.response)
            }
        }
    })
    

    Playground with typesafe code


    要使第三个示例正常工作,您可能只想将headers 声明为允许任何字符串作为键的类型。然后在您的请求选项中使用该对象。

    const headers: { [name: string]: string } = {
        Accept: 'application/json',
    }
    const requestOptions = {
        credentials: 'include',
        headers,
    }
    
    requestOptions.headers['Auth-Token'] = 'abc123';
    

    Playground

    【讨论】:

    • 你能看到我的附录吗?我添加了另一个我遇到问题的项目,你能快速看一下吗?这是标题位。我尝试添加全局标题,但没有成功
    • 我仍在学习 TS,代码库需要从旧版更新到 TS。每当我有问题时,我都会放松你怎么样。每个问题是 2 美元,哈哈。每次我都会Venmo你!!!不错的交易!大声笑:-)
    • 赚 200 美元,我会考虑的 :) 但是将旧版 JS 升级到 typescript 可能会很困难,尤其是当代码只是随机添加属性时。我不建议以这种方式学习打字稿。相反,我建议您开始一个新项目,随时构建类型,并强迫自己永远不要使用 any 作为任何类型的类型。
    • 老板的命令.. 将此代码库更新为 typescript :-(
    【解决方案2】:

    你需要更多地定义类型,Typescript 编译器很聪明地从你的代码中推断出类型,但它需要一些帮助:

    function parseResponse(response:Response) {
      return response[response.status === 204 ? 'text' : 'json']();
    }
    

    您从响应中访问成员“文本”或“json”,我假设它具有响应类型。但是类型 Response 没有成员 text 或 json。由于您正在调用表达式,我认为它必须是某种函数。这个接口的定义将使它编译(虽然我不明白这个函数可能是什么):

    interface Response {
        status: number;
        statusText: string;
        error: Error;
        text: ()=>string;
        json: ()=>string;
    }
    

    请注意,在不实际为该函数提供任何实现的情况下扩展接口当然不会在运行时工作

    代码:

       const error = new Error(response ? response.statusText : 'Offline');
       error.response = response; // TS2339: Property 'response' does not exist on type 'Error'.
       throw error;
    

    你必须定义类 Error 否则编译器会抱怨它知道的 Error 类没有成员“response”

    【讨论】:

    • 我认为有一个通用的错误类型?
    猜你喜欢
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多