看一下编译好的JavaScript,你会看到类型断言(转换)消失,因为它只用于编译。现在你告诉编译器somejson
对象是Person
。编译器相信你,但在这种情况下并非如此。
所以这个问题是一个运行时JavaScript问题。
让这个工作的主要目的是以某种方式告诉JavaScript类之间的关系是什么。所以...
- 找到一种方法来描述类之间的关系。
- 根据这个关系数据创建一些东西来自动将json映射到类。
有很多方法可以解决这个问题,但我会举一个例子来说明问题。这应该有助于描述需要完成的工作。
说我们有这个类:
class Person {
name: string;
child: Person;
public giveName() {
return this.name;
}
}
这JSON数据:
{
name: 'John',
child: {
name: 'Sarah',
child: {
name: 'Jacob'
}
}
}
自动映射这是Person
情况下,我们需要告诉JavaScript的类型是如何相关。我们不能使用TypeScript类型的信息,因为一旦它被编译,我们就会失去它。一种实现这一点的方法是通过在描述此类型的类型上使用静态属性。例如:
class Person {
static relationships = {
child: Person
};
name: string;
child: Person;
public giveName() {
return this.name;
}
}
然后下面是处理基于该关系数据为我们创造的对象可重复使用的函数的例子:
function createInstanceFromJson<T>(objType: { new(): T; }, json: any) {
const newObj = new objType();
const relationships = objType["relationships"] || {};
for (const prop in json) {
if (json.hasOwnProperty(prop)) {
if (newObj[prop] == null) {
if (relationships[prop] == null) {
newObj[prop] = json[prop];
}
else {
newObj[prop] = createInstanceFromJson(relationships[prop], json[prop]);
}
}
else {
console.warn(`Property ${prop} not set because it already existed on the object.`);
}
}
}
return newObj;
}
现在下面的代码将工作:
const someJson = {
name: 'John',
child: {
name: 'Sarah',
child: {
name: 'Jacob'
}
}
};
const person = createInstanceFromJson(Person, someJson);
console.log(person.giveName()); // John
console.log(person.child.giveName()); // Sarah
console.log(person.child.child.giveName()); // Jacob
Playground
理想情况下,最好的方法是使用实际读取TypeScript代码的东西,并创建一个持有类之间关系的对象。这样我们不需要手动维护关系并担心代码更改。例如,现在重构代码对于此设置有点风险。我不确定此刻存在类似的情况,但这绝对有可能。
替代解决方案
我才意识到我已经回答了类似的问题有一个稍微不同的解决方案(不涉及虽然嵌套数据)。你可以在这里阅读一些更多的想法:
JSON to TypeScript class instance?
类型转换纯粹是编译器/ IDE的提示。它永远不会将方法添加到您的纯Javascript对象。所以你需要将JSON数据实例化为一个Person对象,这是没有办法的。您可以轻松编写一个实用程序函数来为您实例化对象的数组/树。在那个笔记上,演员如何帮助你处理一系列对象?你仍然需要迭代数组并转换每个元素,对吧? –