javascript - 在 typescript 中导入 JSON 时如何禁用/断言/覆盖推断类型

标签 javascript json typescript

我正在使用 typescript 2.9 中的“resolveJsonModule”功能来导入 json 文件。假设 json 文件如下所示:

{
  "Nabokov": {
    "Pale Fire": {
      "Pages": "200",
      "Edition": "Paperback",

    },
    "Pnin": {
      "Pages": "150",
      "Edition": "Hardcover"
    },
    "Lolita": {
      "Pages": "150",
      "Edition": "Paperback",
      "Year": "1955"
    }
  },
  "Joyce": {
    "Ulysses": {
      "Pages": "800",
      "Language": "English"
    },
    "Finnegan's Wake": {
      "Pages": "1200",
      "Language": "Gibberish"
    }
  }
}

我通过以下方式导入它:

从“../resources/catalog.json”导入目录

好的,当它被导入时,TypeScript 将自动为其定义类型。例如,当我尝试编写一个可以返回作者/书籍信息的函数时,这对我来说就成了问题。

我只想做

function getBook(author: string, title: string) {
  return catalog[author][title]
}

我得到一个“元素隐式具有“任何”类型,因为“字符串”类型的表达式...”所以它希望我将作者定义为“Nabokov” | “乔伊斯”但是 由于 JSON 文件将永远扩展,并且我随时都不知道其中会包含什么,因此我想“泛化”导入对象的类型,使其类似于 [key: string]。

最佳答案

尝试以下操作:

type C = typeof catalog;
function getBook<T extends keyof C>(author: T, title: keyof C[T]) {
    return catalog[author][title]
}

getBook("Nabokov", "Lolita"); // OK
getBook("Joyce", "Lolita"); // Not OK

这是一个playground来演示。

更新

根据您的用例,您不应限制参数的类型,而应该这样做:

function getBook(author: string, title: string) {
    try {
        return (catalog as any)[author][title]
    } catch(e) {
        // do error handling here
    }
}

更新2

上面提到的方法或多或少都绕过了TypeScript。如果确实想确保类型安全,这里有真正的 TypeScript 方法来完成同样的事情。

type B = {
    Pages: string;
    Edition?: string;
    Year?: string;
    Language?: string;
};
type C = {
    [index: string]: {
        [index:string]: B
    }
};

function getBook(author: string, title: string): B | undefined {
    const cat: C = catalog;
    if(author in cat && title in cat[author]) {
        return cat[author][title];
    } else {
        // do error handling here
        return undefined;
    }
}

查看此playground .

关于javascript - 在 typescript 中导入 JSON 时如何禁用/断言/覆盖推断类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56861367/

相关文章:

javascript - Angular 使用全局拦截器

javascript - 带有 JS 切换的纯 CSS 复选框不起作用

java - 带有日期对象的 Jersey + Jackson 反序列化失败

javascript - 如何将用户属性添加到 Javascript Azure Function 的服务总线主题输出

javascript - TypeScript 类中缺少方法

angular - ngOnInit 中的属性集导致 "type error: this.student is undefined"

javascript - Firefox 和 Chrome 中不可靠的 javascript 正则表达式测试

javascript - 如何检查客户端(机器人)的最高角色位置

JavaScript 正则表达式解析带有 html 中属性值的 JSON 字符串

javascript - Three.js 导入的 JSON 模型不接收/转换阴影