J'ai un objet JSON analysé à partir d'une chaîne.
Disons que cet objet a une propriété appelée "Name" dont la valeur peut être une simple chaîne ou un tableau de chaînes ou même un objet qui stocke des informations à son sujet.

Au moment de l'exécution, je veux pouvoir trouver le type de valeur (chaîne/tableau/objet) et s'il s'agit d'un objet, convertissez-le dans la bonne classe et exécutez une méthode basée sur cela.

J'ai une idée de la façon dont je vais m'y prendre, mais le seul problème est que je ne sais pas comment convertir l'objet dans le bon type.

Par exemple, j'ai une classe qui accepte deux chaînes et une autre classe qui accepte une chaîne et un nombre. Je veux que le programme voie celui auquel il correspond, puis le transpose dans la bonne classe.

J'espère avoir été assez clair si plus d'informations sont nécessaires, faites-le moi savoir.

ÉDITER:

Voici la solution que j'ai utilisée pour que cela fonctionne (du moins pour moi, ce n'est peut-être pas la meilleure solution dans tous les cas).

J'ai une classe abstraite appelée 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;
    }
}

Il a la méthode validateData qui prend un objet (généralement l'objet JSON) et valide qu'il a toutes les variables de l'analyseur. Si les données sont valides, il appellera une méthode abstraite protégée appelée cloneObject.

Voici une classe simple appelée MinMaxParrser qui étend 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;
        }
    }

Comme vous pouvez le voir, il a la méthode cloneObject qui renvoie essentiellement une instance d'un nouveau MinMaxParser

Et enfin, dans le programme principal, j'ai un tableau const de tous les parseurs disponibles en déclarant un objet "sample"

const availableParsers: Parser[] = [new MinMaxParser()];

Quand je veux trouver un parseur valide, j'utilise cette méthode

private findValidParser(data: Object): Parser {
    let found = null;
    availableParsers.forEach(parser => {
        let clone = parser.clone(data);
        if (clone !== null) {
            found = clone;
        }
    });

    return found;
}

Le findValidParser me renvoie un analyseur ou null, je vérifie null et s'il n'est pas null, je peux appeler en toute sécurité la méthode parse() que j'ai créée.

3
Aviv Biton 13 mars 2019 à 09:16

2 réponses

Meilleure réponse

Utilisez typeof et les surcharges de fonction pour obtenir de meilleurs conseils de type :

// 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);
 } /*...*/
}
0
Jonas Wilms 13 mars 2019 à 07:05

Utilisez ce qui suit pour vérifier chaque

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))
0
AZ_ 13 mars 2019 à 06:37