টাইপস্ক্রিপ্টে একটি অভিধান ঘোষণা করুন এবং প্রারম্ভিক করুন


248

নিম্নলিখিত কোড দেওয়া

interface IPerson {
   firstName: string;
   lastName: string;
}

var persons: { [id: string]: IPerson; } = {
   "p1": { firstName: "F1", lastName: "L1" },
   "p2": { firstName: "F2" }
};

কেন আরম্ভ হয় না? সর্বোপরি, দ্বিতীয় বস্তুর "সর্বশেষ নাম" বৈশিষ্ট্য নেই।


11
দ্রষ্টব্য: এটি এর পরে ঠিক করা হয়েছে (কোনটি সঠিক টিএস সংস্করণ তা নিশ্চিত নয়)। Index signatures are incompatible. Type '{ firstName: string; }' is not assignable to type 'IPerson'. Property 'lastName' is missing in type '{ firstName: string; }'.
ভিসিতে

উত্তর:


289

সম্পাদনা করুন : এটি সর্বশেষতম টিএস সংস্করণে স্থির করা হয়েছে। ওপি'র পোস্টে @ সাইমন_উইভারের মন্তব্যটি উদ্ধৃত করে:

দ্রষ্টব্য: এটি এর পরে ঠিক করা হয়েছে (কোনটি সঠিক টিএস সংস্করণ তা নিশ্চিত নয়)। আপনি যেমন আশা করবেন তেমন আমি এই ত্রুটিগুলি ভিএস এ পেয়েছিIndex signatures are incompatible. Type '{ firstName: string; }' is not assignable to type 'IPerson'. Property 'lastName' is missing in type '{ firstName: string; }'.


প্রজ্ঞাপনে প্রাথমিক তথ্য পাস করার সময় দৃশ্যত এটি কাজ করে না। আমি অনুমান করি এটি টাইপস্ক্রিপ্টের একটি বাগ, সুতরাং আপনার প্রকল্পের সাইটে একটি উত্থাপন করা উচিত।

আপনি উদাহরণস্বরূপ ঘোষণা এবং প্রারম্ভিককরণে উদাহরণস্বরূপ ভাগ করে টাইপ করা অভিধানটি ব্যবহার করতে পারেন:

var persons: { [id: string] : IPerson; } = {};
persons["p1"] = { firstName: "F1", lastName: "L1" };
persons["p2"] = { firstName: "F2" }; // will result in an error

3
আপনার idপ্রতীকটির দরকার কী? মনে হয় এটি অপ্রয়োজনীয়।
কিউইক

4
idপ্রতীকটি ব্যবহার করে আপনি ঘোষণা করতে পারবেন অভিধানের কীগুলির প্রকারটি কী হওয়া উচিত। উপরোক্ত ঘোষণার সাথে, আপনি নিম্নলিখিতগুলি করতে পারবেন না:persons[1] = { firstName: 'F1', lastName: 'L1' }
থোমাক্স

2
এই সিনট্যাক্সটি সর্বদা কোনও কারণে ভুলে যান!
এডিডুওল্ড

12
idপ্রতীক মত কিছু নামে করা যাবে এবং সহজে কোড পাঠযোগ্য করতে যে ভাবে পরিকল্পনা করা হয়েছিল। উদাহরণস্বরূপ { [username: string] : IPerson; }
গাই পার্ক

1
@ রোবস্টে আমি লোডাশের সন্ধানের পদ্ধতিটি ব্যবহার করব বা যদি আপনি কোনও স্থানীয় সমাধান পছন্দ করেন তবে আপনি অবজেক্ট.এন্ট্রিগুলিতে তৈরি করতে পারেন । আপনি যদি কীগুলির সম্পূর্ণ তালিকা পেতে আগ্রহী হন তবে অবজেক্ট.কিজ
থোমাক্স

82

টাইপস্ক্রিপ্টে অভিধান অবজেক্ট ব্যবহার করার জন্য আপনি নীচের মত ইন্টারফেস ব্যবহার করতে পারেন:

interface Dictionary<T> {
    [Key: string]: T;
}

এবং, এটি আপনার শ্রেণীর সম্পত্তি ধরণের জন্য ব্যবহার করুন।

export class SearchParameters {
    SearchFor: Dictionary<string> = {};
}

এই ক্লাসটি ব্যবহার এবং আরম্ভ করার জন্য,

getUsers(): Observable<any> {
        var searchParams = new SearchParameters();
        searchParams.SearchFor['userId'] = '1';
        searchParams.SearchFor['userName'] = 'xyz';

        return this.http.post(searchParams, 'users/search')
            .map(res => {
                return res;
            })
            .catch(this.handleError.bind(this));
    }

61

আমি থোমাক্সের সাথে একমত যে ইনিশিয়ালাইজেশন টাইপ চেকিং ত্রুটি একটি টাইপস্ক্রিপ্ট বাগ। তবে, আমি এখনও সঠিক টাইপ চেকিং সহ একক বিবৃতিতে ডিকশনারি ডিক্লেয়ার এবং আরম্ভ করার উপায় খুঁজে পেতে চেয়েছিলাম। এই প্রয়োগটি দীর্ঘতর, তবে এটি containsKey(key: string)এবং remove(key: string)পদ্ধতি হিসাবে অতিরিক্ত কার্যকারিতা যুক্ত করে । আমার সন্দেহ হয় যে একবার জেনেরিকগুলি 0.9 রিলিজ পাওয়া গেলে এটি সরল করা যেতে পারে।

প্রথমে আমরা বেস অভিধান ক্লাস এবং ইন্টারফেস ঘোষণা করি। সূচকটির জন্য ইন্টারফেসটি প্রয়োজনীয় কারণ শ্রেণিগুলি সেগুলি প্রয়োগ করতে পারে না।

interface IDictionary {
    add(key: string, value: any): void;
    remove(key: string): void;
    containsKey(key: string): bool;
    keys(): string[];
    values(): any[];
}

class Dictionary {

    _keys: string[] = new string[];
    _values: any[] = new any[];

    constructor(init: { key: string; value: any; }[]) {

        for (var x = 0; x < init.length; x++) {
            this[init[x].key] = init[x].value;
            this._keys.push(init[x].key);
            this._values.push(init[x].value);
        }
    }

    add(key: string, value: any) {
        this[key] = value;
        this._keys.push(key);
        this._values.push(value);
    }

    remove(key: string) {
        var index = this._keys.indexOf(key, 0);
        this._keys.splice(index, 1);
        this._values.splice(index, 1);

        delete this[key];
    }

    keys(): string[] {
        return this._keys;
    }

    values(): any[] {
        return this._values;
    }

    containsKey(key: string) {
        if (typeof this[key] === "undefined") {
            return false;
        }

        return true;
    }

    toLookup(): IDictionary {
        return this;
    }
}

এখন আমরা ব্যক্তি নির্দিষ্ট ধরণের এবং অভিধান / অভিধান ইন্টারফেস ঘোষণা করি। আমরা কীভাবে ওভাররাইড করে values()এবং toLookup()সঠিক প্রকারগুলি ফিরিয়ে আনতে পার্সনডেটের অভিধানে নোট করুন ।

interface IPerson {
    firstName: string;
    lastName: string;
}

interface IPersonDictionary extends IDictionary {
    [index: string]: IPerson;
    values(): IPerson[];
}

class PersonDictionary extends Dictionary {
    constructor(init: { key: string; value: IPerson; }[]) {
        super(init);
    }

    values(): IPerson[]{
        return this._values;
    }

    toLookup(): IPersonDictionary {
        return this;
    }
}

এবং এখানে একটি সাধারণ সূচনা এবং ব্যবহারের উদাহরণ:

var persons = new PersonDictionary([
    { key: "p1", value: { firstName: "F1", lastName: "L2" } },
    { key: "p2", value: { firstName: "F2", lastName: "L2" } },
    { key: "p3", value: { firstName: "F3", lastName: "L3" } }
]).toLookup();


alert(persons["p1"].firstName + " " + persons["p1"].lastName);
// alert: F1 L2

persons.remove("p2");

if (!persons.containsKey("p2")) {
    alert("Key no longer exists");
    // alert: Key no longer exists
}

alert(persons.keys().join(", "));
// alert: p1, p3

খুব সহায়ক নমুনা কোড। "ইন্টারফেস আইডি অভিধান" একটি ছোট টাইপো ধারণ করে, কারণ এখানে আইফারসনের একটি উল্লেখ রয়েছে।
mgs

পাশাপাশি উপাদান গণনা কার্যকর করতে খুব ভাল
লাগবে

@dmck ঘোষণাটি টাইপস্ক্রিপ্ট 1.5.0-বিটাcontainsKey(key: string): bool; দিয়ে কাজ করে না । এটি পরিবর্তন করা উচিত । containsKey(key: string): boolean;
অমরজিৎ সিং 8

1
আপনি জেনেরিক প্রকারের যত্ন কেন করেন না? অভিধান <টি>, তারপরে পার্সোনাল ডিকশনারি ক্লাস তৈরি করার দরকার নেই। আপনি এটিকে এভাবে ঘোষণা করেন: বিভিন্ন ব্যক্তি = নতুন অভিধান <আইফারসন> ();
বেনোইট

1
আমি এই জাতীয় জেনারিক অভিধানটি কার্যকরভাবে ব্যবহার করেছি। আমি এটি এখানে পেয়েছি: fabiolandoni.ch/…
CAK2

5

এখানে @dmck থেকে অনুপ্রাণিত আরও সাধারণ অভিধান প্রয়োগ রয়েছে

    interface IDictionary<T> {
      add(key: string, value: T): void;
      remove(key: string): void;
      containsKey(key: string): boolean;
      keys(): string[];
      values(): T[];
    }

    class Dictionary<T> implements IDictionary<T> {

      _keys: string[] = [];
      _values: T[] = [];

      constructor(init?: { key: string; value: T; }[]) {
        if (init) {
          for (var x = 0; x < init.length; x++) {
            this[init[x].key] = init[x].value;
            this._keys.push(init[x].key);
            this._values.push(init[x].value);
          }
        }
      }

      add(key: string, value: T) {
        this[key] = value;
        this._keys.push(key);
        this._values.push(value);
      }

      remove(key: string) {
        var index = this._keys.indexOf(key, 0);
        this._keys.splice(index, 1);
        this._values.splice(index, 1);

        delete this[key];
      }

      keys(): string[] {
        return this._keys;
      }

      values(): T[] {
        return this._values;
      }

      containsKey(key: string) {
        if (typeof this[key] === "undefined") {
          return false;
        }

        return true;
      }

      toLookup(): IDictionary<T> {
        return this;
      }
    }

3

আপনি যদি কোনও সম্পত্তি উপেক্ষা করতে চান তবে একটি প্রশ্ন চিহ্ন যুক্ত করে এটি বিকল্প হিসাবে চিহ্নিত করুন:

interface IPerson {
    firstName: string;
    lastName?: string;
}

1
প্রশ্নের পুরো বিষয়টি হ'ল কেন প্রদত্ত কোড কোনও শেষ নাম সরবরাহ না করে সংকলিত হয়েছে ...
পিয়েরে আরলাড

-1

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

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

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

গ্রন্থাগারটিকে ts-জেনেরিক-সংগ্রহ-লিনক বলা হয়

গিটহাবের উত্স কোড:

https://github.com/VeritasSoftware/ts-generic-collections

NPM:

https://www.npmjs.com/package/ts-generic-collections-linq

এই লাইব্রেরির সাহায্যে আপনি সংগ্রহগুলি তৈরি করতে (যেমন List<T>) তৈরি করতে পারেন এবং নীচের মত দেখাচ্ছে সেগুলি জিজ্ঞাসা করতে পারেন ।

    let owners = new List<Owner>();

    let owner = new Owner();
    owner.id = 1;
    owner.name = "John Doe";
    owners.add(owner);

    owner = new Owner();
    owner.id = 2;
    owner.name = "Jane Doe";
    owners.add(owner);    

    let pets = new List<Pet>();

    let pet = new Pet();
    pet.ownerId = 2;
    pet.name = "Sam";
    pet.sex = Sex.M;

    pets.add(pet);

    pet = new Pet();
    pet.ownerId = 1;
    pet.name = "Jenny";
    pet.sex = Sex.F;

    pets.add(pet);

    //query to get owners by the sex/gender of their pets
    let ownersByPetSex = owners.join(pets, owner => owner.id, pet => pet.ownerId, (x, y) => new OwnerPet(x,y))
                               .groupBy(x => [x.pet.sex])
                               .select(x =>  new OwnersByPetSex(x.groups[0], x.list.select(x => x.owner)));

    expect(ownersByPetSex.toArray().length === 2).toBeTruthy();

    expect(ownersByPetSex.toArray()[0].sex == Sex.F).toBeTruthy();
    expect(ownersByPetSex.toArray()[0].owners.length === 1).toBeTruthy();
    expect(ownersByPetSex.toArray()[0].owners.toArray()[0].name == "John Doe").toBeTruthy();

    expect(ownersByPetSex.toArray()[1].sex == Sex.M).toBeTruthy();
    expect(ownersByPetSex.toArray()[1].owners.length == 1).toBeTruthy();
    expect(ownersByPetSex.toArray()[1].owners.toArray()[0].name == "Jane Doe").toBeTruthy();

এর জন্য কোনও এনপিএম প্যাকেজটি খুঁজে পাচ্ছে না
হ্যারি

1
@ হ্যারি - এনপিএম প্যাকেজটিকে "ts-জেনেরিক-সংগ্রহ-লিংক" বলা হয়
অ্যাডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.