অভিধানের ধরণ হিসাবে সি স্ক্রিপ্ট অবজেক্টস টাইপ করুন #


335

আমার কাছে কিছু জাভাস্ক্রিপ্ট কোড রয়েছে যা অভিধান হিসাবে শব্দগুলি ব্যবহার করে; উদাহরণস্বরূপ, কোনও 'ব্যক্তি' অবজেক্ট ইমেল ঠিকানার বাইরে কিছু ব্যক্তিগত বিবরণ ধারণ করবে।

var people = {<email> : <'some personal data'>};

adding   > "people[<email>] = <data>;" 
getting  > "var data = people[<email>];" 
deleting > "delete people[<email>];"

এটি কি টাইপস্ক্রিপ্টে বর্ণনা করা সম্ভব? বা আমি একটি অ্যারে ব্যবহার করতে হবে?


5
পুরানো পোস্ট তবে মনে রাখবেন যে ES6 মানচিত্র রয়েছে
ওল্ড ব্যাডম্যান গ্রে

উত্তর:


546

টাইপস্ক্রিপ্টের নতুন সংস্করণগুলিতে আপনি ব্যবহার করতে পারেন:

type Customers = Record<string, Customer>

পুরানো সংস্করণগুলিতে আপনি ব্যবহার করতে পারেন:

var map: { [email: string]: Customer; } = { };
map['foo@gmail.com'] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['bar@hotmail.com'] = 'x'; // Not OK, 'x' is not a customer

আপনি যদি পুরো সময়টি টীকাটি প্রতিবার টাইপ করতে না চান তবে আপনি একটি ইন্টারফেসও তৈরি করতে পারেন:

interface StringToCustomerMap {
    [email: string]: Customer;
}

var map: StringToCustomerMap = { };
// Equivalent to first line of above

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

5
আপনি এটি জানেন, তবে এই পদ্ধতির সাথে কয়েকটি সম্ভাব্য গোটাচাও রয়েছে, বড়টি হ'ল সমস্ত সদস্যের মাধ্যমে পুনরাবৃত্তি করার কোনও নিরাপদ এবং সহজ উপায় নেই। এই কোডটি উদাহরণস্বরূপ, এটি দেখায়map দুটি সদস্য রয়েছে: (<any> অবজেক্ট.প্রোটোটাইপ) s কিছু = ফাংশন () {}; ক্লাস গ্রাহক {} var মানচিত্র: {[ইমেল: স্ট্রিং]: গ্রাহক; } = {}; মানচিত্র ['foo@gmail.com '] = নতুন গ্রাহক (); (মানচিত্রে ভ্যার আই) এর জন্য {কনসোল.লগ (মানচিত্র [i])}
কেন স্মিথ

5
আপনি এটি থেকে সরান?
টিডিএভার

24
আর একটি আকর্ষণীয় পদ্ধতির হ'ল: ইন্টারফেস ম্যাপস্ট্রিংটো <টি> key [কী: স্ট্রিং]: টি; var map:MapStringTo<Customer> = {};
The

1
লক্ষ করুন যে সূচির সীমাবদ্ধতা আর কাজ করে না। আরও পড়ুন।
ডেভিড শেরেট 13'15

127

মানচিত্রের মতো অবজেক্টটি ব্যবহার করার পাশাপাশি , কিছু সময়ের জন্য একটি আসল Mapঅবজেক্ট রয়েছে যা ES6 তে সংকলন করার সময়, বা ES6 টাইপ-সংজ্ঞা সহ একটি পলিফিল ব্যবহার করার সময় টাইপস্ক্রিপ্টে পাওয়া যায় :

let people = new Map<string, Person>();

এটি Objectসামান্য ভিন্ন সিনট্যাক্স সহ আরও অনেকের মতো একই কার্যকারিতা সমর্থন করে :

// Adding an item (a key-value pair):
people.set("John", { firstName: "John", lastName: "Doe" });

// Checking for the presence of a key:
people.has("John"); // true

// Retrieving a value by a key:
people.get("John").lastName; // "Doe"

// Deleting an item by a key:
people.delete("John");

মানচিত্রের মতো বস্তু ব্যবহারের ক্ষেত্রে এটির একা একাধিক সুবিধা রয়েছে যেমন:

  • নন-স্ট্রিং ভিত্তিক কীগুলির জন্য সমর্থন, উদাহরণস্বরূপ সংখ্যা বা বস্তু, যার কোনওটিই সমর্থন করে না Object(না,Object সমর্থন করে না সংখ্যাগুলি সমর্থন করে না, এটি তাদের স্ট্রিংগুলিতে রূপান্তর করে)
  • ব্যবহার না করার সময় ত্রুটির জন্য কম জায়গা --noImplicitAny, যেমন Mapসর্বদা একটি থাকে কী টাইপ এবং মান ধরণের থাকে, যেখানে কোনও বস্তু শক্তিশালী হতে পারে সূচক-স্বাক্ষর
  • আইটেম যুক্ত করার / মুছে ফেলার কার্যকারিতা (কী-মানযুক্ত জোড়া) কোনও কাজের বৈশিষ্ট্য তৈরির বিপরীতে কাজের জন্য অনুকূলিত করা হয়Object

অতিরিক্তভাবে, কোনও Mapকাজ সাধারণ কাজের জন্য আরও শক্তিশালী এবং মার্জিত এপিআই সরবরাহ করে, যার বেশিরভাগই সহজ Objectসহায়তার মাধ্যমে একসাথে সহায়তা কার্যকারিতা হ্যাক করা ছাড়া পাওয়া যায় না (যদিও এর মধ্যে কিছুগুলির জন্য ES5 টার্গেটের জন্য বা নীচে সম্পূর্ণ ES6 পুনরাবৃত্তকারী / পুনরাবৃত্ত পলিফিল প্রয়োজন):

// Iterate over Map entries:
people.forEach((person, key) => ...);

// Clear the Map:
people.clear();

// Get Map size:
people.size;

// Extract keys into array (in insertion order):
let keys = Array.from(people.keys());

// Extract values into array (in insertion order):
let values = Array.from(people.values());

2
সেটা খুবই ভালো! তবে দুঃখের বিষয় এটি ব্যবহার করে ভুল সিরিয়ালাইজড হয়ে গেছে JSON.stringify(), সুতরাং এটি সকেট.ওয়ের জন্য উদাহরণস্বরূপ ব্যবহার করা যেতে পারে :(
লায়ন

@ লায়ন - ভাল হ্যাঁ, Mapসিরিয়ালাইজেশন বরং মজার is আমি, একের জন্য সিরিয়ালাইজ করার আগে কী-মান-জোড় অবজেক্টগুলিতে রূপান্তর সম্পাদন করি এবং তারপরে ফিরে (উদাহরণস্বরূপ অবজেক্ট { key: "John", value: { firstName: "John" } })।
জন ওয়েইজ

2
আমি একটি সরল পুরানো অবজেক্টের পরিবর্তে মানচিত্রটি ব্যবহার করার ভুল করেছি এবং সিরিয়ালাইজেশন সত্যই আমাকে পেয়েছে। আমার মতে স্পষ্ট চালাও।
ব্যবহারকারী378380

1
এটা সুন্দর. অবশেষে মানচিত্রে ডুবতে আপনি আমাকে অনুপ্রাণিত করলেন বলে খুব খুশী। কীগুলি দৃ key়ভাবে টাইপ করা এত সহজ যেহেতু এটি আমার স্বাভাবিক কীম্যাপ / অভিধান কাঠামোগুলি প্রতিস্থাপন করবে।
মেথোডিশিয়ান

77

আপনি এর মতো টেম্পলেটযুক্ত ইন্টারফেস ব্যবহার করতে পারেন:

interface Map<T> {
    [K: string]: T;
}

let dict: Map<number> = {};
dict["one"] = 1;

7
নোট করুন যে এটি es6 মানচিত্রের ধরণের সাথে সংঘর্ষে। অন্য উত্তরের চেয়ে ভাল কারণ সূচকের সীমাবদ্ধতা উপেক্ষা করা হয়।
ওল্ড ব্যাডম্যান গ্রে

অভিধানে কী কী আছে কিনা তা আমি কীভাবে পরীক্ষা করব?
সামনারিক

ডিক.হসনপ্রপার্টি ('কী')
দিমিতর মাজলেকভ

1
বিভ্রান্তি এড়াতে আমি মানচিত্রের পরিবর্তে অভিধান ব্যবহার করি এবং আপনি আক্ষরিক অবজেক্টের স্বরলিপি ব্যবহার করতে পারেন:let dict: Dictionary<number> = { "one": 1, "two": 2 };
ফিলিহো

8

আপনি টাইপ স্ক্রিপ্টে রেকর্ড টাইপ ব্যবহার করতে পারেন:

export interface nameInterface { 
    propName : Record<string, otherComplexInterface> 
}

5

লোড্যাশের একটি সাধারণ অভিধান প্রয়োগ রয়েছে এবং এতে টাইপস্ক্রিপ্টের ভাল সমর্থন রয়েছে

লোডাশ ইনস্টল করুন:

npm install lodash @types/lodash --save

আমদানি এবং ব্যবহার:

import { Dictionary } from "lodash";
let properties : Dictionary<string> = {
    "key": "value"        
}
console.log(properties["key"])

3

আপনি এটির Recordজন্য ব্যবহার করতে পারেন :

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

উদাহরণ (অ্যাপয়েন্টমেন্টের স্ট্যাটাস এনাম এবং কিছু মেটা ডেটার মধ্যে একটি ম্যাপিং):

  const iconMapping: Record<AppointmentStatus, Icon> = {
    [AppointmentStatus.Failed]: { Name: 'calendar times', Color: 'red' },
    [AppointmentStatus.Canceled]: { Name: 'calendar times outline', Color: 'red' },
    [AppointmentStatus.Confirmed]: { Name: 'calendar check outline', Color: 'green' },
    [AppointmentStatus.Requested]: { Name: 'calendar alternate outline', Color: 'orange' },
    [AppointmentStatus.None]: { Name: 'calendar outline', Color: 'blue' }
  }

মান হিসাবে ইন্টারফেস সহ এখন:

interface Icon { Name: string Color: string }

ব্যবহার:

const icon: SemanticIcon = iconMapping[appointment.Status]


এটি খুব দরকারী। আপনি একটি স্ট্রিং ব্যবহার করতে চান enumবা class/objectজন্য AppointmentStatus- অথবা এটা ব্যাপার?
ড্রেনাই

আমার জন্য এটি একটি enum। আমার আপডেট হওয়া উত্তরটি দেখুন।
নিক এন।

@ ড্রেনাই কোনও বিষয় নয়, আপনি যা পছন্দ করেন
নিক এন।

-2

এখানে একটি লাইব্রেরি রয়েছে যা টাইপ স্ক্রিপ্টে দৃ strongly়ভাবে টাইপযুক্ত, প্রশ্নের যোগ্য সংগ্রহগুলি সরবরাহ করে।

সংগ্রহগুলি হ'ল:

  • তালিকা
  • অভিধান

লাইব্রেরিকে ts-জেনেরিক-সংগ্রহ বলা হয় । ( গিটহাবের উত্স কোড )

আপনি একটি অভিধান তৈরি করতে এবং নীচের মত এটি জিজ্ঞাসা করতে পারেন:

  it('firstOrDefault', () => {
    let dictionary = new Dictionary<Car, IList<Feature>>();

    let car = new Car(1, "Mercedez", "S 400", Country.Germany);
    let car2 = new Car(2, "Mercedez", "S 500", Country.Germany);

    let features = new List<Feature>();

    let feature = new Feature(1, "2 - Door Sedan");
    features.add(feature);

    dictionary.add(car, features);

    features = new List<Feature>();
    feature = new Feature(2, "4 - Door Sedan");
    features.add(feature);

    dictionary.add(car2, features);

    //query
    let first = dictionary.firstOrDefault(x => x.key.name == "Mercedez");

    expect(first.key.id = 1);
  });
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.