রানটাইমে কোনও অবজেক্টের ক্লাসের নাম পান


271

টাইপস্ক্রিপ্ট ব্যবহার করে রানটাইমের সময় কি কোনও সামগ্রীর শ্রেণি / প্রকারের নাম পাওয়া সম্ভব?

class MyClass{}

var instance = new MyClass();
console.log(instance.????); // Should output "MyClass"

3
এখানে দেখুন । রানটাইমের সময় আপনি জাভাস্ক্রিপ্ট চালাচ্ছেন।
ম্যাট বার্ল্যান্ড

1
আপনি কীভাবে টাইপস্ক্রিপ্ট ফাইলটিতে কনস্ট্রাক্টরের নাম পাবেন? আপনি টাইপস্ক্রিপ্ট পদ্ধতিতে (.ts ফাইলে) this.constructor.name করতে পারবেন না।
শেল্ডন_কুপার

উত্তর:


461

সহজ উত্তর:

class MyClass {}

const instance = new MyClass();

console.log(instance.constructor.name); // MyClass
console.log(MyClass.name);              // MyClass

তবে: সাবধান হন যে মিনিডযুক্ত কোড ব্যবহার করার সময় নামটি সম্ভবত আলাদা হবে।


14
দুর্ভাগ্যক্রমে MyClass.name একটি ES6 বৈশিষ্ট্য তাই এটি আই 11 এ কাজ করে না।
ভিজি

9
প্রকারলিপি এতে ত্রুটি ফেলবে। করা উচিতlet instance: any = this.constructor; console.log(instance.name);
সুবাশ

7
কাস্টিং এড়ানোর anyজন্য console.log(instance.constructor['name']);
নিখুঁতভাবে @ শুশ করুন

1
@ সুবাশ আপনি পরিবর্তে কোনও প্রকার-ঘোষণাও তৈরি করতে পারেন: interface Function { name: string; }- এটি "নেটিভ" সংজ্ঞাটি প্রসারিত করবে।
জন ওয়েইজ

1
MyClass.nameআপনি যদি আপনার কোডটি ক্ষুদ্র করে দিচ্ছেন তবে ভাল কাজ করবে না। কারণ এটি ক্লাসের নামটি ছোট করে দেবে।
রাগান্বিত হ্যাকার

28

আমি জানি আমি পার্টিতে দেরি করেছি, তবে আমি দেখতে পাচ্ছি যে এটি খুব কার্যকর হয়।

var constructorString: string = this.constructor.toString();
var className: string = constructorString.match(/\w+/g)[1]; 

বিকল্পভাবে ...

var className: string = this.constructor.toString().match(/\w+/g)[1];

উপরের কোডটি পুরো কনস্ট্রাক্টর কোডটিকে স্ট্রিং হিসাবে পেয়ে থাকে এবং সমস্ত 'শব্দ' পেতে একটি রেজেক্স প্রয়োগ করে। প্রথম শব্দটি 'ফাংশন' এবং দ্বিতীয় শব্দটি শ্রেণীর নাম হওয়া উচিত।

আশাকরি এটা সাহায্য করবে.


4
দুঃখিত, নিশ্চিত। সাধারণত, আপনি সংশোধন, কদর্যকরণ এবং অন্যান্য পোস্ট প্রসেসিং সিস্টেম ব্যবহার করেন। সুতরাং প্রোডাকশন সার্ভারে আপনার শ্রেণির নাম একই হবে না। এবং আপনার কোড কাজ করবে না। ক্লাসের নাম পাওয়ার জন্য আমি সত্যিই খুব ভাল সমাধান পাইনি। সবচেয়ে উপযুক্ত উপায় হ'ল আপনার শ্রেণীর নামের সাথে একটি স্থিতিশীল পরিবর্তনশীল def
ডিমা কুড়িলো

23

আমার সমাধানটি ক্লাসের নামের উপর নির্ভর করা ছিল না। অবজেক্ট কনস্ট্রাক্টর.নেম থিওরিতে কাজ করে। তবে আপনি যদি আয়নিকের মতো কিছুতে টাইপস্ক্রিপ্ট ব্যবহার করে থাকেন তবে আপনি প্রোডাকশনে যাওয়ার সাথে সাথে এটি শিখাতে উঠে যাবে কারণ আয়নিকের প্রোডাকশন মোড জাভাস্ক্রিপ্ট কোডকে ছোট করে দেয়। সুতরাং ক্লাসগুলি "এ" এবং "ই" এর মতো নামযুক্ত জিনিসগুলি পেয়ে যায়।

আমি যেটা শেষ করেছিলাম তা আমার সমস্ত অবজেক্টে টাইপনেম ক্লাস ছিল যা কনস্ট্রাক্টর ক্লাসের নাম নির্ধারণ করেছে। তাই:

export class Person {
id: number;
name: string;
typeName: string;

constructor() {
typeName = "Person";
}

হ্যাঁ আসলেই জিজ্ঞাসা করা হয়নি। তবে এমন কোনও কিছুর জন্য কনস্ট্রাক্টর.নাম ব্যবহার করা যা সম্ভবত রাস্তায় নামিয়ে দেওয়া সম্ভবত মাথা ব্যথার জন্য ভিক্ষা করছে।



14

আপনার প্রথমে উদাহরণটি কাস্ট করা দরকার anyকারণ Functionধরণের সংজ্ঞাতে কোনও nameসম্পত্তি নেই।

class MyClass {
  getName() {
    return (<any>this).constructor.name;
    // OR return (this as any).constructor.name;
  }
}

// From outside the class:
var className = (<any>new MyClass()).constructor.name;
// OR var className = (new MyClass() as any).constructor.name;
console.log(className); // Should output "MyClass"

// From inside the class:
var instance = new MyClass();
console.log(instance.getName()); // Should output "MyClass"

হালনাগাদ:

টাইপস্ক্রিপ্ট ২.৪ (এবং সম্ভাব্য পূর্বে) দিয়ে কোডটি আরও পরিষ্কার হতে পারে:

class MyClass {
  getName() {
    return this.constructor.name;
  }
}

// From outside the class:
var className = (new MyClass).constructor.name;
console.log(className); // Should output "MyClass"

// From inside the class:
var instance = new MyClass();
console.log(instance.getName()); // Should output "MyClass"

2
Property 'name' does not exist on type 'Function'.
টাইপস্ক্রিপ্ট ২.6.২ এ

(this as {}).constructor.nameবা এর (this as object).constructor.nameচেয়ে ভাল anyকারণ আপনি আসলে স্বতঃপূরণ পাবেন :-)
সাইমন_উইভার

5

Angular2 এ এটি উপাদানগুলির নাম পেতে সহায়তা করতে পারে:

    getName() {
        let comp:any = this.constructor;
        return comp.name;
    }

কমপ: যে কোনও প্রয়োজন কারণ টাইপস্ক্রিপ্ট সংকলন ত্রুটি জারি করবে কারণ প্রাথমিকভাবে ফাংশনটির সম্পত্তির নাম নেই।


5
তবে আপনি যদি আপনার কোডটি ছোট / uglify করেন তবে এটি কাজ করবে না
অ্যাডমির সাবানোভিচ

কোনও উপাদানটির ব্যবহারযোগ্য 'নাম' element.nativeElementপেতে আপনি @Optional() element: ElementRef<HTMLElement>if (element != null && element.nativeElement.tagName.startsWith('APP-')) { this.name = element.nativeElement.tagName; }
ট্যাগের

(এবং ট্যাগের নামগুলি
পরিমার্জন করা হয়

4

সম্পূর্ণ টাইপস্ক্রিপ্ট কোড

public getClassName() {
    var funcNameRegex = /function (.{1,})\(/;
    var results  = (funcNameRegex).exec(this["constructor"].toString());
    return (results && results.length > 1) ? results[1] : "";
}

4
আপনি যদি আপনার টাইপ স্ক্রিপ্ট / জাভাস্ক্রিপ্ট কোডটি ন্যূনতম করে ও অনুকূলিত করেন তবে আপনি কিছু সমস্যা পেতে পারেন। এটি ফাংশনটির নাম পরিবর্তন করতে পারে এবং তারপরে আপনার শ্রেণীর নামের তুলনাটি ভুল হতে পারে।
এন্টি

4
  • "। যোগ করার জন্য ছিল । প্রোটোটাইপ ব্যবহার": myClass.prototype.constructor.name
  • অন্যথায় নিম্নলিখিত কোড সহ myClass.constructor.name:, আমার মধ্যে টাইপস্ক্রিপ্ট ত্রুটি ছিল:

error TS2339: Property 'name' does not exist on type 'Function'


0

এই সমাধানটি মিনিফিকেশন উগ্লিফিকেশনের পরে কাজ করে তবে মেটাডেটা সহ ক্লাসগুলি সাজানোর প্রয়োজন requires

আমরা মেটাডেটা সহ আমাদের সত্তা ক্লাসগুলি সাজানোর জন্য কোড জেনারেশনটি ব্যবহার করি:

@name('Customer')
export class Customer {
  public custId: string;
  public name: string;
}

তারপরে নিম্নলিখিত সহায়িকার সাথে গ্রাস করুন:

export const nameKey = Symbol('name');

/**
 * To perserve class name though mangling.
 * @example
 * @name('Customer')
 * class Customer {}
 * @param className
 */
export function name(className: string): ClassDecorator {
  return (Reflect as any).metadata(nameKey, className);
}

/**
 * @example
 * const type = Customer;
 * getName(type); // 'Customer'
 * @param type
 */
export function getName(type: Function): string {
  return (Reflect as any).getMetadata(nameKey, type);
}

/**
 * @example
 * const instance = new Customer();
 * getInstanceName(instance); // 'Customer'
 * @param instance
 */
export function getInstanceName(instance: Object): string {
  return (Reflect as any).getMetadata(nameKey, instance.constructor);
}

-2

আপনি কী ধরনের প্রত্যাশা করবেন তা যদি আপনি ইতিমধ্যে জানেন (উদাহরণস্বরূপ, যখন কোনও পদ্ধতিটি ইউনিয়নের ধরণটি দেয় ) তবে আপনি প্রকার রক্ষক ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, আদিম ধরণের জন্য আপনি টাইপফ গার্ড ব্যবহার করতে পারেন :

if (typeof thing === "number") {
  // Do stuff
}

জটিল ধরণের জন্য আপনি একটি উদাহরণ গার্ড ব্যবহার করতে পারেন :

if (thing instanceof Array) {
  // Do stuff
}

আমার ধারণা এটির কারণ আপনার উত্তর প্রশ্নের সাথে সম্পর্কিত নয়। প্রশ্নটি ছিল ক্লাসের নামটি শর্তসাপেক্ষে উদাহরণস্বরূপ স্টাফ করবেন না।
ড্যানিয়েল লইজেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.