乐闻世界logo
搜索文章和话题

如何将 json 对象强制转换为 typescript 的 interface?

7 个月前提问
3 个月前修改
浏览次数224

6个答案

1
2
3
4
5
6

要将 JSON 对象转换为 TypeScript 类,你可以创建一个类,其属性和类型与 JSON 对象的键和值类型相匹配。以下是一个简单的例子,展示了这个过程。

假设我们有如下的 JSON 对象:

json
{ "id": 1, "name": "Alice", "email": "alice@example.com", "isActive": true }

我们可以创建一个 TypeScript 类来表示这个 JSON 对象:

typescript
class User { id: number; name: string; email: string; isActive: boolean; constructor(id: number, name: string, email: string, isActive: boolean) { this.id = id; this.name = name; this.email = email; this.isActive = isActive; } }

为了将 JSON 对象实例化为这个类的实例,我们可以编写一个函数来处理转换:

typescript
function createUser(json: any): User { return new User(json.id, json.name, json.email, json.isActive); } // JSON 对象 const json = { "id": 1, "name": "Alice", "email": "alice@example.com", "isActive": true }; // 将 JSON 对象转换为 User 类的实例 const user = createUser(json);

下面是一些额外的注意事项:

  1. 类型校验: 在实际应用中,你可能需要验证 JSON 对象包含了所有必需的属性,并且它们的类型是正确的。TypeScript 的类型系统在编译时提供了一些帮助,但运行时你可能需要额外的校验。

  2. 可选属性: 如果 JSON 对象中的某些属性可能不存在,你应该在 TypeScript 类中将这些属性标记为可选。例如:

typescript
class User { id: number; name: string; email: string; isActive?: boolean; // 可选属性 // 如果 isActive 是可选的,构造函数参数也应相应地标记为可选 constructor(id: number, name: string, email: string, isActive?: boolean) { this.id = id; this.name = name; this.email = email; this.isActive = isActive; } }
  1. 复杂对象: 如果你的 JSON 对象包含嵌套的对象或数组,你需要确保对应的 TypeScript 类型也反映了这个结构。

  2. 自动化: 如果你经常需要进行这种转换,可以考虑使用一些自动化工具,如 quicktype 或其他在线转换器,它们可以根据 JSON 输入自动生成 TypeScript 类型定义。

2024年6月29日 12:07 回复

您无法将 Ajax 请求中的普通 JavaScript 结果简单地转换为原型 JavaScript/TypeScript 类实例。有多种技术可以实现这一点,并且通常涉及复制数据。除非您创建该类的实例,否则它不会有任何方法或属性。它将仍然是一个简单的 JavaScript 对象。

虽然如果您只处理数据,则可以只转换为接口(因为它纯粹是编译时结构),但这需要您使用 TypeScript 类,该类使用数据实例并使用该数据执行操作。

复制数据的一些示例:

  1. 将 AJAX JSON 对象复制到现有对象中
  2. 在 JavaScript 中将 JSON 字符串解析为特定的对象原型

本质上,你只需:

shell
var d = new MyRichObject(); d.copyInto(jsonResult);
2024年6月29日 12:07 回复

我遇到了同样的问题,我找到了一个可以完成这项工作的库: https: //github.com/pleerock/class-transformer

它的工作原理如下:

shell
let jsonObject = response.json() as Object; let fooInstance = plainToClass(Models.Foo, jsonObject); return fooInstance;

它支持嵌套的孩子,但你必须装饰你的班级成员。

2024年6月29日 12:07 回复

在 TypeScript 中,您可以使用接口和泛型进行类型断言,如下所示:

shell
var json = Utilities.JSONLoader.loadFromFile("../docs/location_map.json"); var locations: Array<ILocationMap> = JSON.parse(json).location;

其中 ILocationMap 描述了数据的形状。此方法的优点是您的 JSON 可以包含更多属性,但形状满足接口的条件。

但是,这不会添加类实例方法。

2024年6月29日 12:07 回复

如果您使用的是 ES6,请尝试以下操作:

shell
class Client{ name: string displayName(){ console.log(this.name) } } service.getClientFromAPI().then(clientData => { // Here the client data from API only have the "name" field // If we want to use the Client class methods on this data object we need to: let clientWithType = Object.assign(new Client(), clientData) clientWithType.displayName() })

但遗憾的是,此方法不适用于嵌套对象

2024年6月29日 12:07 回复

我发现一篇关于将 JSON 通用转换为 Typescript 类的非常有趣的文章:

http://cloudmark.github.io/Json-Mapping/

您最终得到以下代码:

shell
let example = { "name": "Mark", "surname": "Galea", "age": 30, "address": { "first-line": "Some where", "second-line": "Over Here", "city": "In This City" } }; MapUtils.deserialize(Person, example); // custom class
2024年6月29日 12:07 回复

你的答案