تايب سكريبت - الحصول على خصائص الكلاس
هل هناك طريقة للحصول على أسماء الخصائص للفئة في TypeScript؟
في المثال، أود أن 'أصف' الفئة A أو أي فئة وأحصل على مصفوفة من خصائصها (ربما فقط العامة منها؟)، هل هذا ممكن؟ أم يجب أن أقوم بإنشاء الكائن أولاً؟
class A {
private a1;
private a2;
/** Getters and Setters */
}
class Describer<E> {
toBeDescribed:E ;
describe(): Array<string> {
/**
* Do something with 'toBeDescribed'
*/
return ['a1', 'a2']; //<- Example
}
}
let describer = new Describer<A>();
let x= describer.describe();
/** x should be ['a1', 'a2'] */
الإجابة رقم 1
كود TypeScript هذا
class A {
private a1;
public a2;
}
يتم تجميعه إلى هذا الكود جافا سكريبت
class A {
}
هذا لأن الخصائص في جافاسكريبت تبدأ بالوجود فقط بعد أن يكون لها قيمة ما. عليك أن تعطي الخصائص بعض القيمة.
class A {
private a1 = "";
public a2 = "";
}
يترجم إلى
class A {
constructor() {
this.a1 = "";
this.a2 = "";
}
}
مع ذلك، لا يمكنك الحصول على الخصائص من الصف فقط (يمكنك الحصول على الدوال فقط من النموذج الأولي). يجب عليك إنشاء نسخة. ثم يمكنك الحصول على الخصائص عن طريق استدعاء Object.getOwnPropertyNames().
let a = new A();
let array = return Object.getOwnPropertyNames(a);
array[0] === "a1";
array[1] === "a2";
مطبق على مثالِك
class Describer {
static describe(instance): Array<string> {
return Object.getOwnPropertyNames(instance);
}
}
let a = new A();
let x = Describer.describe(a);
الإجابة رقم 2
بعض الإجابات خاطئة جزئياً، وبعض الحقائق فيها خاطئة جزئياً أيضاً.
أجب عن سؤالك: نعم! يمكنك.
في تايب سكريبت
class A {
private a1;
private a2;
}
ينشئ الشيفرة التالية في جافاسكريبت:
var A = /** @class */ (function () {
function A() {
}
return A;
}());
كما قال @Erik_Cupal، يمكنك فقط أن تفعل:
let a = new A();
let array = return Object.getOwnPropertyNames(a);
لكن هذا غير مكتمل. ماذا يحدث إذا كان لدى صفك منشئ مخصص؟ تحتاج إلى القيام بخدعة مع Typescript لأنه لن يتم تجميعه. تحتاج إلى التعيين كـ any:
let className:any = A;
let a = new className();// the members will have value undefined
الحل العام سيكون:
class A {
private a1;
private a2;
constructor(a1:number, a2:string){
this.a1 = a1;
this.a2 = a2;
}
}
class Describer{
describeClass( typeOfClass:any){
let a = new typeOfClass();
let array = Object.getOwnPropertyNames(a);
return array;//you can apply any filter here
}
}
للفهم الأفضل، سيشير هذا اعتمادًا على السياق.
الإجابة رقم 3
حل آخر، يمكنك ببساطة التكرار على مفاتيح الكائن هكذا، ملاحظة: يجب عليك استخدام كائن مُنشأ يحتوي على خصائص موجودة:
printTypeNames<T>(obj: T) {
const objectKeys = Object.keys(obj) as Array<keyof T>;
for (let key of objectKeys)
{
console.log('key:' + key);
}
}
الإجابة رقم 4
مجرد للمرح
class A {
private a1 = void 0;
private a2 = void 0;
}
class B extends A {
private a3 = void 0;
private a4 = void 0;
}
class C extends B {
private a5 = void 0;
private a6 = void 0;
}
class Describer {
private static FRegEx = new RegExp(/(?:this\.)(.+?(?= ))/g);
static describe(val: Function, parent = false): string[] {
var result = [];
if (parent) {
var proto = Object.getPrototypeOf(val.prototype);
if (proto) {
result = result.concat(this.describe(proto.constructor, parent));
}
}
result = result.concat(val.toString().match(this.FRegEx) || []);
return result;
}
}
console.log(Describer.describe(A)); // ["this.a1", "this.a2"]
console.log(Describer.describe(B)); // ["this.a3", "this.a4"]
console.log(Describer.describe(C, true)); // ["this.a1", ..., "this.a6"]
تحديث: إذا كنت تستخدم مُنشئات مخصصة، فإن هذه الوظيفة ستتوقف عن العمل.
