[英]JS / TS determine if a JSON object implements a class or interface
I have a JSON object parsed from a string. 我有一个从字符串解析的JSON对象。
Let's say this object has a property called "Name" the value of it can be a simple string or an array of strings or even an object that store some information about it. 假设这个对象有一个名为“Name”的属性,它的值可以是一个简单的字符串,也可以是一个字符串数组,甚至是一个存储有关它的信息的对象。
In runtime I want to be able to find the value type (string/array/object) and if it is an object cast it into the correct class and run a method based on that. 在运行时,我希望能够找到值类型(字符串/数组/对象),如果它是一个对象,则将其转换为正确的类并运行基于该方法的方法。
I have the idea on how I am going to go about this but the only problem is that I am not sure how to convert the object to the correct type. 我有关于如何解决这个问题的想法,但唯一的问题是我不确定如何将对象转换为正确的类型。
For example, I have a class which accepts two strings and another class that accepts a string and a number. 例如,我有一个接受两个字符串的类和另一个接受字符串和数字的类。 I want the program to see which one it matches and then cast it to the correct class.
我希望程序看到它匹配哪一个,然后将它转换为正确的类。
Hope I was clear enough if more information is needed please let me know. 希望我很清楚,如果需要更多信息,请告诉我。
EDIT: 编辑:
Here is the solution I used to make this work (at least for me, it may not be the best solution in every case). 这是我用来完成这项工作的解决方案(至少对我而言,它可能不是每种情况下的最佳解决方案)。
I have an abstract class called Parser 我有一个名为Parser的抽象类
export abstract class Parser {
abstract parse(): string;
clone(dataObject: object): Parser {
if (this.validateData(dataObject) == false) return null;
return this.cloneObject(dataObject);
}
protected abstract cloneObject(dataObject: object): Parser;
protected validateData(data: object): boolean {
const parserKeys = Object.keys(this);
const dataKeys = Object.keys(data);
for (let i = 0; i < parserKeys.length; i++) {
const parserKeyName = parserKeys[i];
if (typeof this[parserKeyName] === "function") continue;
const index = dataKeys.indexOf(parserKeyName);
if (
index == -1 ||
typeof data[dataKeys[i]] !== typeof this[parserKeyName]
)
return false;
}
return true;
}
}
It has the method validateData which takes an object (the JSON Object usually) and validate that it has all the variables the Parser has. 它有方法validateData,它接受一个对象(通常是JSON对象)并验证它具有Parser所具有的所有变量。 If the data is valid it will call a protected abstract method called cloneObject.
如果数据有效,它将调用名为cloneObject的受保护抽象方法。
Here is a simple class called MinMaxParrser that extends Parser 这是一个名为MinMaxParrser的简单类,它扩展了Parser
import { Parser } from "./Parser";
import { randomNumber } from "./utils";
export class MinMaxParser extends Parser {
min: 0;
max: 1;
constructor() {
super();
this.min = 0;
this.max = 1;
}
parse(): string {
return randomNumber(this.min, this.max).toString();
}
cloneObject(dataObject: object): MinMaxParser {
let newParser = new MinMaxParser();
newParser.min = dataObject["min"];
newParser.max = dataObject["max"];
return newParser;
}
}
As you can see, it has the cloneObject method which basically returns an instance of a new MinMaxParser 如您所见,它具有cloneObject方法,该方法基本上返回新MinMaxParser的实例
And finally, in the main program, I have a const array of all the available parsers by declaring a "sample" object 最后,在主程序中,我通过声明一个“sample”对象来获得所有可用解析器的const数组
const availableParsers: Parser[] = [new MinMaxParser()];
When I want to find a valid parser I use this method 当我想找到一个有效的解析器时,我使用这个方法
private findValidParser(data: Object): Parser {
let found = null;
availableParsers.forEach(parser => {
let clone = parser.clone(data);
if (clone !== null) {
found = clone;
}
});
return found;
}
The findValidParser returns me a parser or null, I check for null and if it is not null i can safely call the parse() method i created. findValidParser返回一个解析器或null,我检查null,如果它不为null,我可以安全地调用我创建的parse()方法。
Use the following to check each 使用以下方法检查每个
let obj = {}; let str = ''; let num = 0; let array = []; console.log(Array.isArray(array)) console.log(typeof obj === 'object') console.log(typeof str === 'string') console.log(!isNaN(num))
Use typeof
and function overloads to get better type hints: 使用
typeof
和function重载来获得更好的类型提示:
// narrow down types to get better typings
function parse(a: string, b: {}, c: string): Parser1;
//...
// implement generically
function parse(a: any, b: any, c: any): Parser {
if(typeof a === "string" && typeof b === "object" && typeof c === "string") {
return Parser1.parse(a, b, c);
} /*...*/
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.