首页 > 解决方案 > TypeScript 对于可能在其中一个字段中具有嵌套字段或平面字符串的 json 的正确类型是什么?

问题描述

TS 的新手,我遇到了一个问题,我很惭愧地承认我比我希望的更难弄清楚。我有以下从端点获取的 json

 {
   "status":"ok",
   "upload_id":"someid",
   "url":{
      "url":"https://foo.bar",
      "fields":{
         "ble":"bla",
         "foo":"boo"
      }
   }
}

我就是这样拿的

    fetch(`https://foo.bar/foo`)
        .then(response => response.json())
        .then((result: Record<string, Record<string, string>>) => {
            console.log(result)
            const info: Record<string, string> = result.url;
            const url: string = info.url;
            const upload_id: string = result.upload_id
        })

但问题是打字似乎不匹配。它需要一个 Record<string, string> 但它正在获取一个用于上传 id 的字符串。我该如何让 typescript 知道 upload_id 是有效的?

标签: typescript

解决方案


您必须定义类型以及您期望的属性。

当您定义时,Record<string, string>您是在告诉 typescript 您期望一个具有字符串键和字符串值的通用对象。

但是,如果您尝试访问特定属性,即

const upload_id: string = result.upload_id

Typescript 不能保证它是一个字符串,因为它可能upload_id不存在。为了解决这个问题,您必须定义您期望/知道将存在的属性。

type UrlResponse = {
  url: {
    url: string
    // etc
  }
}

type Response = {
  status: string,
  upload_id: string,
  url: UrlResponse
}

然后,当您在代码中引用此类型时,您不应再收到如下错误:

fetch(`https://foo.bar/foo`)
        .then(response => response.json())
        .then((result: Response) => {
            console.log(result)
            const info: UrlResponse = result.url;
            const url: string = info.url;
            const upload_id: string = result.upload_id
        })

推荐阅读