简体   繁体   English

如何在 React 中根据 typescript 接口检查 JSON object 的类型

[英]How to check type of a JSON object against typescript interface in React

I have a result JSON object being passed onto a function which I would need to check the type of it against a Typescript interface definition model, in order to be perform specific rendering changes prior displaying it. I have a result JSON object being passed onto a function which I would need to check the type of it against a Typescript interface definition model, in order to be perform specific rendering changes prior displaying it.

I am facing an issue, where the string matches all the interface types as it goes through the checks, using (jsonResult as TypeScriptInterfaceName) and simply doesnt deliver the correct value subsequently.我面临一个问题,其中字符串在通过检查时匹配所有接口类型,使用 (jsonResult as TypeScriptInterfaceName) 并且随后根本不提供正确的值。

I tried the class transformer library as well with no luck.我也尝试了 class 变压器库,但没有运气。 Whats the best way to explicitly check and fail the string against the typescript definition.什么是根据 typescript 定义显式检查字符串并使其失败的最佳方法。

Thank you.谢谢你。

interface ParentOne {
    id: string;
    title: string;
    child: Child
}
interface Child {
    id: string;
    title: string;
}
**JSON ONE**
{
    id: value,
    title: value,
    child: [{}],
}


interface ParentTwo {
    id: string;
    title: string;
    directory: Directory
}
interface Directory {
    id: string;
    title: string;
}

**JSON TWO**
{
    id: value,
    title: value,
    directory: [{}],
}

When you're parsing JSON the resulting type will be any .当您解析 JSON 时,结果类型将为any Type information doesn't exist at runtime, so Typescript can't help you there.运行时不存在类型信息,因此 Typescript 无法帮助您。

What we do is create a JSON-Schema file that describes the JSON file, and then we use a JSON-Schema validator like ajv to validate if the incoming JSON object matches the schema.我们要做的是创建一个 JSON-Schema 文件来描述 JSON 文件,然后我们使用像ajv这样的 JSON-Schema 验证器来验证传入的 JSON ZA8CFDE6331BD59EB2AC96F8911C4B666 是否匹配。

We then use a tool like json-schema-to-typescript to generate types based on the schemas.然后我们使用像json-schema-to-typescript这样的工具来根据模式生成类型。

Our validation function finally looks something like this:我们的验证 function 最终看起来像这样:

function validateBody<T>(body: unknown, jsonSchemaId: string): asserts body is T {

   // Do validation or throw error

}

This means that from a single JSON-Schema, we get:这意味着从单个 JSON-Schema 中,我们得到:

  1. Typescript types in the backend Typescript 类型在后端
  2. Typescript types in the frontend Typescript 类型在前端
  3. Documentation文档
  4. A server-side validator with useful errors.带有有用错误的服务器端验证器。
  5. Type-safety (after validation)类型安全(验证后)

Because you don't have the interface definitions at runtime you can't count on them for sanity checking, what you might do is something like the following.因为您在运行时没有接口定义,所以您不能指望它们进行完整性检查,您可能会执行以下操作。

Given some useful interfaces给定一些有用的接口

interface ParentOne {
    id: string;
    title: string;
    child: Child
}
interface Child {
    id: string;
    title: string;
}

interface ParentTwo {
    id: string;
    title: string;
    directory: Directory
}
interface Directory {
    id: string;
    title: string;
}

We want a way to use those nice interfaces我们想要一种使用这些漂亮界面的方法

const processParentOne = (p: ParentOne) => {
  console.log(p.child);
}

const processParentTwo = (p: ParentTwo) => {
  console.log(p.directory);
}

So we cast them as soon as we can infer the type所以我们一可以推断出类型就转换它们

const processionJson = (data: any) => {
  if (!!data.child) {
    processParentOne(data as ParentOne);
  } else if(!!data.directory) {
    processParentTwo(data as ParentTwo);
  }
}

So that we can do something like这样我们就可以做类似的事情

const p1: ParentOne = {
  id: 'po',
  title: "p1",
  child: {
    id: 'chopo',
    title: 'little'
  }
}

const p2: ParentTwo = {
  id: 'pt',
  title: 'p2',
  directory: {
    id: 'dirpt',
    title: 'dict'
  }
}

// Remove all the type info for example
const json = (Math.random() < .5) 
  ? JSON.stringify(p1) : JSON.stringify(p2);

// pass along "unknown" data type
processionJson(JSON.parse(json))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM