Typescriptのボーンまたはイントロスペクトタイプでクラスを解析します







「あなたはクールなことを思いついた、Styopa」と同僚は私に言った、彼に言われた考えに気づいた。これが真実であることを願っていますが、後で説明する内容にめちゃくちゃ革新的なものがあるとは言いませんが、私の意見では、この資料は依然として興味深いものです。

今日は、Webインターフェイスの開発におけるイントロスペクションの使用、少し一般化されたプログラミングについて説明し、.NETと同様の類似物を持つTypescriptでホイールを再発明します。







?



, .







:







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();
}
      
      





.













?



最初に頭に浮かんだのは、reactのCRUDアプリケーションは、汎用コンポーネントを実装することで作成できるようになったことです。たとえば、テーブルに挿入するフォームを作成する必要があります。どうか、誰もそのようなことを禁じません。







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>
    );
}
      
      





そして、このコンポーネントをこのように使用します。







<TypedForm
    type={Person} />
      
      





さて、テーブル自体も同じ原理で作ることができます。







まとめ



面白いことがわかったと言いたいのですが、次にどうするかはまだはっきりしていません。興味のある方やご提案がございましたら、コメント欄にご記入ください。とりあえず、またお会いしましょう!ご清聴ありがとうございました!








All Articles