Analyser les classes par os ou types introspectifs dans Typescript







«Vous avez trouvé un truc cool, Styopa», m'a dit un collègue, réalisant l'idée qui lui avait été donnée. J'espère que c'est vrai, même si je ne dirai pas qu'il y a quelque chose d'insensément innovant dans ce qui sera discuté plus tard, cependant, à mon avis, ce matériel est toujours intéressant.

Aujourd'hui, nous allons parler de l'utilisation de l'introspection dans le développement d'interfaces web, un peu de programmation généralisée et nous réinventerons la roue dans Typescript, qui a un analogue similaire dans .NET.







?



, .







:







class Person {
    height: number;
    weight: number;
    bloodPressure: string;
}
      
      





, , , .













, - .







const fields = ObjectFields.of(Person)
      
      







, , , . Object.keys



, keyof



. , , .

, . , , .







interface IObjectField<T extends object> {
    readonly field: keyof T;
    readonly type: string;
    readonly value: any;
}
      
      





, , FieldInfo. :)

, Typescript — .NET. , . , C# .

, .







interface IConstructor<T> {
    new(...args: any[]): T;
}
      
      





, , :







  1. , — .
  2. IObjectField



  3. — .


Typescript.







class ObjectFields<T extends object> extends Array<IObjectField<T>> {
    readonly [n: number]: IObjectField<T>;
    constructor(type: IConstructor<T>) {
        const instance: T = new type();
        const fields: Array<IObjectField<T>> = (Object.keys(instance) as Array<keyof T>)
            .map(x => {
                const valueType = typeof instance[x];
                let result: IObjectField<T> = {
                    field: x,
                    type: valueType === 'object'
                        ? (instance[x] as unknown as object).constructor.name
                        : valueType,
                    value: instance[x]
                }
                return result;
            });
        super(...fields);
    }
}
      
      





"" Person



.







const fields = new ObjectFields(Person);
console.log(fields);
      
      





, .













? . , Object.keys



, Javascript, , . — , , , - . "", - .







class Person {
    height: number = 80;
    weight: number = 188;
    bloodPressure: string = '120-130 / 80-85';
}
      
      





— , .













.







class Material {
    name = "wood";
}

class MyTableClass {
    id = 1;
    title = "";
    isDeleted = false;
    createdAt = new Date();
    material = new Material();
}
      
      





.













?



La première chose qui m'est venue à l'esprit: les applications CRUD dans react peuvent désormais être écrites en implémentant des composants génériques. Par exemple, vous devez créer un formulaire à insérer dans un tableau. S'il vous plaît, personne n'interdit de faire quelque chose comme ça.







interface ITypedFormProps<T extends object> {
    type: IConstructor<T>;
}

function TypedForm<T extends object>(props: ITypedFormProps<T>) {
    return (
        <form>
            {new ObjectFields(props.type).map(f => mapFieldToInput(f))}
        </form>
    );
}
      
      





Et puis utilisez ce composant comme ça.







<TypedForm
    type={Person} />
      
      





Eh bien, la table elle-même peut être fabriquée selon le même principe.







Résumer



Je voudrais dire que la pièce s'est avérée intéressante, mais on ne sait pas encore quoi en faire ensuite. Si vous étiez intéressé ou avez des suggestions, écrivez dans les commentaires, mais pour l'instant, à bientôt! Merci pour l'attention!








All Articles