বিভিন্ন এনাম ভেরিয়েন্টগুলি টাইপস্ক্রিপ্টে কীভাবে কাজ করে?


116

টাইপসক্রিপ্টে এনুম সংজ্ঞায়িত করার বিভিন্ন উপায় রয়েছে:

enum Alpha { X, Y, Z }
const enum Beta { X, Y, Z }
declare enum Gamma { X, Y, Z }
declare const enum Delta { X, Y, Z }

যদি আমি Gammaরানটাইম থেকে কোনও মান ব্যবহার করার চেষ্টা করি তবে আমি একটি ত্রুটি পেয়েছি কারণ Gammaসংজ্ঞায়িত নয়, তবে এটি কি Deltaবা এরকম নয় Alpha? এখানে constবা declareঘোষণার অর্থ কী ?

একটি preserveConstEnumsসংকলক পতাকাও রয়েছে - এটি কীভাবে এইগুলির সাথে ইন্টারেক্ট করে?


উত্তর:


247

টাইপস্ক্রিপ্টে এনামগুলিতে চারটি ভিন্ন দিক রয়েছে যা সম্পর্কে আপনার সচেতন হওয়া দরকার। প্রথমত, কিছু সংজ্ঞা:

"অনুসন্ধান অবজেক্ট"

আপনি যদি এই এনাম লিখেন:

enum Foo { X, Y }

টাইপস্ক্রিপ্ট নিম্নলিখিত বস্তু নির্গত করবে:

var Foo;
(function (Foo) {
    Foo[Foo["X"] = 0] = "X";
    Foo[Foo["Y"] = 1] = "Y";
})(Foo || (Foo = {}));

আমি এটিকে লুকিং অবজেক্ট হিসাবে উল্লেখ করব । এর উদ্দেশ্য দ্বিগুণ: স্ট্রিং থেকে সংখ্যাগুলিতে ম্যাপিং হিসাবে পরিবেশন করা , যেমন লেখার সময় Foo.Xবা Foo['X'], এবং সংখ্যার থেকে স্ট্রিংয়ের ম্যাপিং হিসাবে পরিবেশন করা । ডিবাগিং বা লগিংয়ের উদ্দেশ্যে সেই বিপরীত ম্যাপিংটি কার্যকর - আপনার প্রায়শই মান থাকবে 0বা 1আপনি সংশ্লিষ্ট স্ট্রিংটি পেতে চান "X"বা "Y"

"ঘোষণা" বা " পরিবেষ্টিত "

টাইপস্ক্রিপ্টে, আপনি কম্পাইলারের যে জিনিসগুলি সম্পর্কে জানতে হবে সেগুলি "ঘোষণা" করতে পারেন, তবে আসলে কোডটি নির্গত নয় not আপনার কাছে jQuery এর মতো লাইব্রেরি রয়েছে যখন কিছু বস্তুর সংজ্ঞা দেয় (উদাহরণস্বরূপ $) যেগুলি সম্পর্কে আপনি টাইপ তথ্য চান তবে সংকলক দ্বারা তৈরি কোনও কোডের প্রয়োজন হয় না This অনুমান এবং অন্যান্য ডকুমেন্টেশনগুলি "পরিবেষ্টিত" প্রসঙ্গে হিসাবে এইভাবে করা ঘোষণাকে বোঝায়; এটি নোট করা গুরুত্বপূর্ণ যে কোনও .d.tsফাইলের সমস্ত ঘোষণাগুলি "পরিবেষ্টিত" (হয় স্পষ্টত পরিবর্তনকারী প্রয়োজন হয় declareবা এটি স্পষ্টতই তা হ'ল, ঘোষণার ধরণের উপর নির্ভর করে)।

"ইনলাইনিং"

পারফরম্যান্স এবং কোড আকারের কারণে, প্রায়শই একটি সংখ্যার সমতুল্য সংকলন করার সময় এনাম সদস্যের প্রতিস্থাপন করা ভাল pre

enum Foo { X = 4 }
var y = Foo.X; // emits "var y = 4";

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


এনামস, তারা কীভাবে কাজ করবে?

একটি এনামের প্রতিটি দিক দিয়ে এটি ভাঙা যাক। দুর্ভাগ্যক্রমে, এই চারটি বিভাগের প্রতিটি অন্যের থেকে শর্তাবলী রেফারেন্সে চলেছে, সুতরাং আপনার সম্ভবত এই পুরো জিনিসটি একাধিকবার পড়তে হবে।

গণিত বনাম অ-গণিত (ধ্রুবক)

এনাম সদস্যদের হয় হয় গণনা করা যেতে পারে বা না। অনুমানটি অ-গণিত সদস্যদের অবিচ্ছিন্নভাবে কল করে তবে কনস্টের সাথে বিভ্রান্তি এড়াতে আমি তাদেরকে অ-গণিত বলব ।

একটি গণিত এনাম সদস্য এমন একজন যার মূল্য সংকলন সময়ে জানা যায় না। গণিত সদস্যদের উল্লেখগুলি অবশ্যই ইনলাইন করা যায় না। উল্টোদিকে, অ কম্পিউটেড enum সদস্য যার মানকে একবার হয় কম্পাইল-সময়ে পরিচিত। অ-গণিত সদস্যদের রেফারেন্সগুলি সর্বদা অন্তর্ভুক্ত থাকে।

কোন এনুম সদস্যগণ গণিত হয় এবং কোনটি অ-গণিত হয়? প্রথমে, constএনামের সমস্ত সদস্য স্থির থাকে (যেমন অ-গণিত), নামটি বোঝা যায়। নন-কনস্ট্যান্ট এনুমের জন্য এটি নির্ভর করে আপনি কোনও অ্যাম্বিয়েন্ট (ঘোষিত) এনাম বা অ-অ্যাম্বিয়েন্ট এনাম খুঁজছেন কিনা whether

কোনও declare enum(যেমন পরিবেষ্টিত এনাম) এর সদস্য স্থির থাকে এবং কেবল যদি এর ইনিশিয়ালাইজার থাকে। অন্যথায়, এটি গণনা করা হয়। নোট করুন যে declare enumএকটিতে, শুধুমাত্র সংখ্যাগত প্রারম্ভিকদের অনুমতি দেওয়া হয়। উদাহরণ:

declare enum Foo {
    X, // Computed
    Y = 2, // Non-computed
    Z, // Computed! Not 3! Careful!
    Q = 1 + 1 // Error
}

অবশেষে, অ-ঘোষিত নন-কনস্ট্যান্ট এনামগুলির সদস্যগণ সর্বদা গণনা হিসাবে বিবেচিত হয়। যাইহোক, তাদের আরম্ভকরণের অভিব্যক্তিগুলি স্থিরকারীদের কমিয়ে আনা হয় যদি তারা সংকলন সময়ে গণনীয় হয়। এর অর্থ নন-কনস্ট্যান্ট এনাম সদস্যরা কখনই ইনলাইন হয় না (এই আচরণটি টাইপস্ক্রিপ্ট ১.৫ এ পরিবর্তিত হয়েছে, নীচে "টাইপসক্রিপ্টে পরিবর্তনগুলি দেখুন")

কনট বনাম নন-কনস্ট্যান্ট

const

একটি এনাম ঘোষণায় constপরিবর্তক থাকতে পারে। একটি enum হয় তাহলে const, সব তার সদস্যদের উল্লেখ inlined।

const enum Foo { A = 4 }
var x = Foo.A; // emitted as "var x = 4;", always

সংকলিত এনামগুলি একটি সংক্ষিপ্ত বিবরণ তৈরি করে না। এই কারণে, Fooসদস্যের রেফারেন্সের অংশ ব্যতীত উপরের কোডটিতে রেফারেন্স করা একটি ত্রুটি । Fooরানটাইমের সময় কোনও বস্তু উপস্থিত থাকবে না।

অ const

যদি এনাম ঘোষণাপত্রে constসংশোধক না থাকে তবে সদস্য অ-গণনা করা হয় তবেই তার সদস্যদের রেফারেন্সগুলি ইনলাইন করা হয়। একটি অ-কনস্ট্যান্ট, অ-ঘোষিত এনাম একটি লুকিং অবজেক্ট তৈরি করবে।

ঘোষিত (পরিবেষ্টক) বনাম অ-ঘোষিত

একটি গুরুত্বপূর্ণ উপস্থাপনাটি হ'ল declareটাইপস্ক্রিপ্টের একটি খুব নির্দিষ্ট অর্থ রয়েছে: এই বস্তুটি অন্য কোথাও বিদ্যমান । এটি বিদ্যমান বস্তুগুলি বর্ণনা করার জন্য । ব্যবহার declareযে বস্তু আসলে উপস্থিত না থাকার খারাপ পরিণাম হতে পারে সংজ্ঞায়িত করতে; আমরা পরে এটি অন্বেষণ করব।

ঘোষণা

A declare enumএকটি লুকিং অবজেক্টকে ছাড়বে না। এই সদস্যদের গণনা করা হলে এর সদস্যদের রেফারেন্সগুলি ইনলাইন করা হয় (উপরের দিকে গণিত বনাম অ-গণিত দেখুন)।

এটা খেয়াল করা জরুরী একটি রেফারেন্স যে অন্যান্য ধরনের গুরুত্বপূর্ণ declare enum হয় মঞ্জুরিপ্রাপ্ত যেমন এই কোড না একটি কম্পাইল এরর কিন্তু হবে রানটাইম এ ব্যর্থ:

// Note: Assume no other file has actually created a Foo var at runtime
declare enum Foo { Bar } 
var s = 'Bar';
var b = Foo[s]; // Fails

এই ত্রুটিটি "সংকলককে মিথ্যা বলবেন না" বিভাগের অধীনে আসে। Fooরানটাইমের সময় যদি আপনার কোনও নাম না থাকে তবে লিখবেন না declare enum Foo!

ক - declare const enumএ - এর থেকে আলাদা নয় - const enumপ্রিফারিজ কনস্টেইনামসের ক্ষেত্রে (নীচে দেখুন)।

অ ঘোষণা

একটি অ-ঘোষিত এনাম যদি তা না থাকে তবে একটি লুকিং অবজেক্ট তৈরি করে const। ইনলাইনিং উপরে বর্ণিত হয়।

--preservConstEnums পতাকা

এই পতাকাটির ঠিক এক প্রভাব রয়েছে: অ-ঘোষিত কনস্ট এনামগুলি একটি লুকিং অবজেক্টটি প্রেরণ করবে। ইনলাইনিং প্রভাবিত হয় না। এটি ডিবাগিংয়ের জন্য দরকারী।


সাধারণ ত্রুটি

সর্বাধিক সাধারণ ভুলটি হ'ল declare enumকোনও নিয়মিত ব্যবহার করা enumবা const enumআরও উপযুক্ত be একটি সাধারণ ফর্মটি হ'ল:

module MyModule {
    // Claiming this enum exists with 'declare', but it doesn't...
    export declare enum Lies {
        Foo = 0,
        Bar = 1     
    }
    var x = Lies.Foo; // Depend on inlining
}

module SomeOtherCode {
    // x ends up as 'undefined' at runtime
    import x = MyModule.Lies;

    // Try to use lookup object, which ought to exist
    // runtime error, canot read property 0 of undefined
    console.log(x[x.Foo]);
}

সুবর্ণ নিয়ম মনে রাখবেন: কখনও declareকিছু যে আসলে কোন অস্তিত্ব নেই । ব্যবহার করুন const enumযদি আপনি সবসময় ইনলাইনিং চাই, বা enumআপনি লুকআপ বস্তুর চান।


টাইপস্ক্রিপ্ট পরিবর্তন

টাইপস্ক্রিপ্ট 1.4 এবং 1.5 এর মধ্যে, অ-ঘোষিত নন-কনস্ট্যান্ট এনামগুলির সমস্ত সদস্যকে গণনা হিসাবে বিবেচনা করার জন্য , আচরণের পরিবর্তন হয়েছে ( https://github.com/Mic Microsoft/TypeScript/issues/2183 দেখুন ) তারা স্পষ্টভাবে একটি আক্ষরিক সঙ্গে আরম্ভ করা হয়। এই "বাচ্চাকে আনস্প্লিট করুন", তাই কথা বলার জন্য, অন্তর্নিহিত আচরণটি আরও অনুমানযোগ্য এবং আরও পরিষ্কারভাবে ধারণাটিকে const enumনিয়মিত থেকে পৃথক করে তোলে enum। এই পরিবর্তনের আগে, নিরপেক্ষ এনামগুলির অ-গণিত সদস্যরা আরও আক্রমণাত্মকভাবে ইনলাইন হয়েছিল।


6
একটি সত্যিই দুর্দান্ত উত্তর। এটি কেবল enums নয়, আমার পক্ষে অনেকগুলি বিষয় পরিষ্কার করেছে cleared
ক্লার্ক

1
আমি আশা করি আমি আপনাকে একাধিকবার ভোট দিতে পারতাম ... সেই ব্রেকিং পরিবর্তন সম্পর্কে জানতাম না। সঠিক শব্দার্থক সংস্করণে এটি প্রধান সংস্করণটির জন্য একটি দ্বিধা হিসাবে বিবেচনা করা যেতে পারে: - /
মফেইনিস

বিভিন্ন enumধরণের একটি খুব সহায়ক তুলনা , আপনাকে ধন্যবাদ!
মারিয়াস শুলজ

@ রায়ান এটি খুব সহায়ক, ধন্যবাদ! ঘোষিত এনাম ধরণের যথাযথ উত্পাদন করতে এখন আমাদের কেবল ওয়েব এসেনশিয়াল 2015 প্রয়োজন const
স্টাইলে

19
এই উত্তরটি ১.৪-এর পরিস্থিতি ব্যাখ্যা করে খুব বিশদে চলে গেছে বলে মনে হচ্ছে এবং তারপরে একেবারে শেষে বলেছে "তবে ১.৫ এ সমস্ত পরিবর্তন করেছে এবং এখন এটি অনেক সহজ।" ধরে নিচ্ছি যে আমি জিনিসগুলি সঠিকভাবে বুঝতে পেরেছি, এই উত্তরটি বৃদ্ধ হওয়ার সাথে সাথে এই সংস্থা আরও এবং আরও অনুপযুক্ত হতে চলেছে: আমি সহজ, বর্তমান পরিস্থিতিটিকে প্রথমে রাখার এবং কেবলমাত্র এই কথার পরেই পরামর্শ দেওয়ার পরামর্শ দিচ্ছি "তবে আপনি যদি 1.4 বা তার আগে ব্যবহার করছেন তবে জিনিসগুলি আরও কিছুটা জটিল।
কেআরয়ান

33

এখানে কয়েকটি জিনিস চলছে। কেস কেস কেস যান।

enum

enum Cheese { Brie, Cheddar }

প্রথমত, একটি সরল পুরাতন এনাম। জাভাস্ক্রিপ্ট-এ সংকলিত হয়ে গেলে, এটি একটি সারণী নির্গত করবে।

দেখার টেবিলটি দেখতে এমন দেখাচ্ছে:

var Cheese;
(function (Cheese) {
    Cheese[Cheese["Brie"] = 0] = "Brie";
    Cheese[Cheese["Cheddar"] = 1] = "Cheddar";
})(Cheese || (Cheese = {}));

তারপর আপনি আছে Cheese.Brieটাইপ করা বিষয়, এটা নির্গত Cheese.Brieজাভাস্ক্রিপ্ট যা 0. মূল্যায়ণ মধ্যে Cheese[0]নিঃসরণ করে Cheese[0]এবং আসলে মূল্যায়ণ "Brie"

কনস্ট এনাম

const enum Bread { Rye, Wheat }

আসলে এর জন্য কোনও কোড নির্গত হয় না! এর মানগুলি অন্তর্ভুক্ত। নিম্নলিখিতটি জাভাস্ক্রিপ্টে 0 মানটি নির্গত করে:

Bread.Rye
Bread['Rye']

const enumএর ইনলাইনিং পারফরম্যান্সের কারণে কার্যকর হতে পারে।

তবে কি Bread[0]? এটি রানটাইমের সময় ত্রুটিযুক্ত হবে এবং আপনার সংকলকটি এটি ধরা উচিত। এখানে কোনও সন্ধানের টেবিল নেই এবং সংকলকটি এখানে ইনলাইন করে না।

মনে রাখবেন যে উপরের ক্ষেত্রে, --preserveConstEnums পতাকাটি রুটির জন্য একটি অনুসন্ধান সারণী নির্গত করবে। এর মানগুলি এখনও অন্তর্ভুক্ত থাকবে।

এনাম ঘোষণা

অন্যান্য ব্যবহারের মতো declare, declareকোনও কোড নির্গত করে না এবং আশা করে যে আপনি অন্য কোথাও আসল কোডটি সংজ্ঞায়িত করেছেন। এটি কোনও অনুসন্ধান সারণী নির্গত করে না:

declare enum Wine { Red, Wine }

Wine.RedWine.Redজাভাস্ক্রিপ্টে নির্গত হয়, তবে রেফারেন্সের জন্য কোনও ওয়াইন লুকিং টেবিল থাকবে না যাতে আপনি অন্য কোথাও এটি সংজ্ঞায়িত না করা হলে এটি ত্রুটিযুক্ত।

কনস্ট enum ঘোষণা

এটি কোনও অনুসন্ধান সারণী নির্গত করে না:

declare const enum Fruit { Apple, Pear }

তবে এটি ইনলাইন করে! Fruit.Apple0 প্রকাশ করে তবে Fruit[0]রানটাইমের সময় আবার ত্রুটি বেরিয়ে আসবে কারণ এটি কোনও ইনডিল নয় এবং কোনও অনুসন্ধানের টেবিল নেই।

আমি এই খেলার মাঠে এটি লিখেছি । কোন টাইপস্ক্রিপ্ট কোন জাভাস্ক্রিপ্ট নির্গত তা বোঝার জন্য আমি সেখানে খেলার প্রস্তাব দিই।


1
আমি এই উত্তরটি আপডেট করার পরামর্শ দিচ্ছি: টাইপস্ক্রিপ্ট ৩.৩.৩ অনুসারে Bread[0]একটি সংকলক ত্রুটি নিক্ষেপ করেছে: "একজন
ছারভে

1
হুঁ ... উত্তর কি বলে তার থেকে আলাদা? "তবে রুটি [0] সম্পর্কে কী? এটি রানটাইমের সময় ত্রুটিযুক্ত হবে এবং আপনার সংকলকটি এটি ধরা উচিত There এখানে কোনও দেখার সারণী নেই এবং সংকলকটি এখানে ইনলাইন করে না doesn't"
ক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.