আমি কীভাবে টাইপসক্রিপ্টে কোনও বস্তুর গতিশীলভাবে সম্পত্তি বরাদ্দ করব?


359

আমি যদি জাভাস্ক্রিপ্টের কোনও জিনিসে প্রোগ্রামিকভাবে একটি সম্পত্তি অর্পণ করতে চাই, তবে আমি এটি এটি করব:

var obj = {};
obj.prop = "value";

তবে টাইপস্ক্রিপ্টে এটি একটি ত্রুটি উত্পন্ন করে:

'' Type 'টাইপের মানটিতে সম্পত্তি' প্রোপ 'বিদ্যমান নেই

টাইপস্ক্রিপ্টে কোনও বস্তুর কাছে নতুন কোনও সম্পত্তি বরাদ্দ করার কথা আমার কীভাবে?


1
অবগতির জন্য। আপনি যদি এটি অনুসরণ করতে চান তবে আমি এটি সম্পর্কিত একটি আলোচনা খুলেছি
joshuapoehls

উত্তর:


454

এটি objহিসাবে চিহ্নিত করা সম্ভব any, তবে এটি টাইপস্ক্রিপ্ট ব্যবহারের পুরো উদ্দেশ্যকে পরাস্ত করে। obj = {}ইঙ্গিত objএকটি হয় Object। এটি চিহ্নিত করা anyকোনও অর্থহীন নয়। পছন্দসই ধারাবাহিকতাটি সম্পাদনের জন্য একটি ইন্টারফেস নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা যেতে পারে।

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

বা এটি কমপ্যাক্ট করতে:

var obj: {[k: string]: any} = {};

LooseObjectকী হিসাবে কোনও স্ট্রিং সহ ক্ষেত্রগুলি গ্রহণ করতে পারে এবং anyমান হিসাবে টাইপ করতে পারে।

obj.prop = "value";
obj.prop2 = 88;

এই সমাধানটির আসল কমনীয়তা হ'ল আপনি ইন্টারফেসে টাইপসেফের ক্ষেত্রগুলি অন্তর্ভুক্ত করতে পারেন।

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;

যদিও এটি আসল প্রশ্নের উত্তর দেয়, এখানে @ গ্রেইনক্রিয়েশনগুলির উত্তরটি কীভাবে সমস্যাটির কাছে যেতে পারে সে সম্পর্কে অন্য দৃষ্টিভঙ্গি দিতে পারে।


13
আমি মনে করি এটি এখন সেরা সমাধান। আমি মনে করি যে সময়ে প্রশ্নটি জিজ্ঞাসা করা হয়েছিল এমন সূচক বৈশিষ্ট্যগুলি এখনও টাইপস্ক্রিপ্টে প্রয়োগ করা হয়নি।
পিটার ওলসন

ত্রুটির মতো নেটিভ অবজেক্ট সম্পর্কে কীভাবে
ওয়াইউ

@ ওয়াইও দেশীয় বস্তু যেমন ত্রুটি এবং অ্যারে অবজেক্ট থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। সুতরাং LooseObjectএকটি ত্রুটি হিসাবে নিতে পারেন।
আকাশ কুরিয়ান জোসে

আপনি কি পরীক্ষা করতে পারেন যে বস্তুর একটি নির্দিষ্ট (গতিশীল) সম্পত্তি আছে কিনা?
phhbr

1
এই আলগা বস্তুর জন্য, আপনি কীভাবে সেগুলি গেটর-সেটার আকারে লিখবেন?
জকিংব্যাটম্যান

81

বা সমস্ত একসাথে:

  var obj:any = {}
  obj.prop = 5;

41
টাইপস্ক্রিপ্টের মূল বিষয় কী যদি anyএটির ব্যবহারের জন্য আমাকে অনেক কিছু কাস্ট করতে হয়? আমার
কোডটিতে

16
@ আজাক্সলিউং আপনার যদি এটির প্রয়োজন হয় তবে আপনি এটি ভুল ব্যবহার করছেন।
অ্যালেক্স

2
উপরের অতিরিক্ত সম্পাদনাটি দেখুন যা বস্তুর আগের প্রকারটি সংরক্ষণ করে।
আন্দ্রে ভিয়েনা

6
@ আজাক্সলিউং আপনার খুব কমই কাস্ট করা উচিত any। টাইপস্ক্রিপ্ট সংকলন সময়ে (সম্ভাব্য) ত্রুটিগুলি ধরার জন্য ব্যবহৃত হয়। আপনি যদি anyত্রুটিগুলিকে নিঃশব্দ করার জন্য ফেলে দেন তবে আপনি টাইপ করার শক্তি হারাবেন এবং পাশাপাশি খাঁটি জেএসে ফিরে যেতে পারেন। anyআদর্শভাবে কেবল তখনই ব্যবহার করা উচিত যখন আপনি কোডটি আমদানি করছেন যার জন্য আপনি টিএস সংজ্ঞা লিখতে পারবেন না বা আপনার কোডটি জেএস থেকে
টিএসে

63

আমি anyঅন্য দিকে রাখার প্রবণতা অর্থাৎ var foo:IFoo = <any>{};তাই এরকম কিছু এখনও টাইপসেফ হয়:

interface IFoo{
    bar:string;
    baz:string;
    boo:string;     
}

// How I tend to intialize 
var foo:IFoo = <any>{};

foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";

// the following is an error, 
// so you haven't lost type safety
foo.bar = 123; 

বিকল্পভাবে আপনি এই বৈশিষ্ট্যগুলি alচ্ছিক হিসাবে চিহ্নিত করতে পারেন:

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;    
}

// Now your simple initialization works
var foo:IFoo = {};

এটি অনলাইনে চেষ্টা করুন


5
টাইপ সুরক্ষা রাখে এমন একমাত্র সমাধান হওয়ার জন্য +1। আপনার পরবর্তী সময়ে আপনাকে কামড়ানো বাগগুলি এড়ানোর জন্য আপনি কেবলমাত্র সমস্ত অ-alচ্ছিক সম্পত্তি এটির পরে সরাসরি ইনস্ট্যান্ট করার বিষয়টি নিশ্চিত করুন।
এইডিয়াকাপি

এটি কি আসলে কাজ করে? সংকলনের পরে আমি এখনও আমার জাভাস্ক্রিপ্টে <আরো> {have রেখেছি।
বিভিএস

4
I still have <any>{তাহলে আপনি সংকলন করেন নি
টাইপস্ক্রিপ্ট

4
এই দিন, var foo: IFoo = {} as anyপছন্দ করা হয়। টাইপকাস্টিংয়ের জন্য পুরানো বাক্য গঠনটি টিএসএক্সের সাথে সংঘর্ষ করছিল (টাইপস্ক্রিপ্ট-আইফাইড জেএসএক্স)।
ডন

51

এই সমাধানটি কার্যকর যখন আপনার অবজেক্টের নির্দিষ্ট ধরণের থাকে। অন্য উত্স থেকে বস্তু প্রাপ্ত করার সময় পছন্দ।

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.

7
এটি এক-অফ কার্যের সঠিক সমাধান।
সুন্দরভাবে টাইপ

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

33

যদিও সংকলকটি অভিযোগ করে যে এটি আপনার প্রয়োজন মতো এখনও আউটপুট করা উচিত। তবে এটি কাজ করবে।

var s = {};
s['prop'] = true;

2
হ্যাঁ ঠিক আছে, এটি আসলে স্ক্রিপ্টের মতো টাইপ নয়, আপনি ইন্টেলিজেন্স লুথ করেন।
প্রাগমেচ

25

এটির জন্য আরও একটি বিকল্প হ'ল সম্পত্তি হিসাবে সংগ্রহ হিসাবে অ্যাক্সেস করা:

var obj = {};
obj['prop'] = "value";


2
এটি সবচেয়ে সংক্ষিপ্ত উপায়। Object.assign(obj, {prop: "value"})ES6 / ES2015 থেকেও কাজ করে।
চার্লস

8

আমি অবাক হয়েছি যে উত্তরগুলির কোনওটিই রেজিস্ট্রেশন না করে Object.assign যেহেতু আমি যখনই জাভাস্ক্রিপ্টে "রচনা" সম্পর্কে ভাবি আমি ব্যবহার করি।

এবং এটি টাইপস্ক্রিপ্টে প্রত্যাশার মতো কাজ করে:

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

সুবিধাদি

  • সর্বত্র কারণ আপনি ব্যবহার করতে প্রয়োজন হবে না নিরাপত্তা টাইপ anyএ সব ধরনের
  • টাইপ করা বিষয় এর সমষ্টিগত টাইপ ব্যবহার (যেমন দ্বারা প্রকাশ &যখন ধরণ ঘোষণা objectWithAllProps, যা পরিষ্কারভাবে যোগাযোগ যে আমরা একটি নতুন ধরনের on-the-মাছি (অর্থাত পরিবর্তনশীল) রচনা করবেন)

বিষয়গুলি সচেতন হতে হবে

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

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

8

আপনি স্প্রেড অপারেটরটি ব্যবহার করে পুরানো অবজেক্টের ভিত্তিতে নতুন অবজেক্ট তৈরি করতে পারেন

interface MyObject {
    prop1: string;
}

const myObj: MyObject = {
    prop1: 'foo',
}

const newObj = {
    ...myObj,
    prop2: 'bar',
}

console.log(newObj.prop2); // 'bar'

টাইপস্ক্রিপ্ট মূল অবজেক্টের সমস্ত ক্ষেত্রকে অনুমান করবে এবং ভিএসকোড স্বয়ংক্রিয়ভাবে পূর্ণতা ইত্যাদি করবে etc.


দুর্দান্ত, তবে প্রপ 3 যেমন আপনার প্রোপ 2 ব্যবহার করা দরকার, তা প্রয়োগ করা শক্ত হবে
ya_dimon


5

কোনও বিদ্যমান বস্তুর দ্বারা কোনও সদস্যকে যুক্ত করা সম্ভব

  1. প্রকারটি প্রশস্ত করুন (পড়ুন: ইন্টারফেসটি প্রসারিত / বিশেষজ্ঞ করুন)
  2. মূল অবজেক্টটি প্রসারিত প্রকারে ফেলে দিন
  3. সদস্যটিকে অবজেক্টে যুক্ত করুন
interface IEnhancedPromise<T> extends Promise<T> {
    sayHello(): void;
}

const p = Promise.resolve("Peter");

const enhancedPromise = p as IEnhancedPromise<string>;

enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));

// eventually prints "Hello Peter"
enhancedPromise.sayHello();

1
আমার জন্য সেরা সমাধান। আমি আজ নতুন কিছু শিখেছি, আপনাকে ধন্যবাদ
মরিস

আমি এই কোডটি দিয়ে টিএস 2352 ত্রুটি পেয়েছি
ya_dimon

@ya_dimon টাইপস্ক্রিপ্ট প্লেগ্রাউন্ডে এটি ব্যবহার করে দেখুন: typcriptlang.org/play এটি দুর্দান্ত কাজ করে!
ড্যানিয়েল ডায়েত্রিচ

@ ড্যানিয়েলডিয়েটরিচ এখন কাজ করে .. থেক্স, কী ঘটেছে তার কোনও ধারণা নেই।
ya_dimon

আপনাকে স্বাগতম! শিফট ঘটে;)
ড্যানিয়েল ডিয়েট্রিচ

5

যেহেতু আপনি এটি করতে পারবেন না:

obj.prop = 'value';

যদি আপনার টিএস সংকলক এবং আপনার লিন্টার আপনাকে কঠোর না করে তবে আপনি এটি লিখতে পারেন:

obj['prop'] = 'value';

যদি আপনার টিএস সংকলক বা লিন্টার কঠোর হয় তবে অন্য উত্তরটি টাইপকাস্টের হবে:

var obj = {};
obj = obj as unknown as { prop: string };
obj.prop = "value";

3
Tsconfig.json- এ যদি 'noImpectedAny: মিথ্যা' হয় তবে এটি হয়
লেমুএডএল ADANE

অন্যথায় আপনি গ্রিনক্রিয়েশন উত্তরটি করতে পারেন।
লেবুউইল অ্যাডানে

4

যে কোনও নতুন সম্পত্তি যেকোন ধরণের অবজেক্টে এটি 'যে কোনও' তে টাইপ করে সংরক্ষণ করুন:

var extend = <any>myObject;
extend.NewProperty = anotherObject;

পরে আপনি আপনার বর্ধিত অবজেক্টটিকে 'যে কোনও' তে কাস্ট করে এটি পুনরুদ্ধার করতে পারেন:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;

এটি সম্পূর্ণরূপে সঠিক সমাধান। বলুন আপনার কাছে একটি অবজেক্ট রয়েছে o: অবজেক্টটাইপ; .... পরবর্তীতে আপনি যে কোনও একটিতে ও (কাস্টমাইজ ও) কাস্ট করতে পারেন ne এবং এটি (<নতুন> ও) এর মতো পুনরুদ্ধার করা যায়। কোন সংকলক ত্রুটি এবং কবজ মত কাজ করে না।
ম্যাট অ্যাশলে

এই ব্রেক ইন্টেলিজেন্স ... ইন্টেলিসেন্স চালিয়ে যাওয়া ছাড়া কি এর কোনও উপায় আছে?
প্রাগমেচ

4

গ্যারান্টিটি দিতে যে টাইপটি একটি Object(অর্থাত্ মূল-মান জোড়া ), ব্যবহার করুন:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'

4
  • মামলা 1:

    var car = {type: "BMW", model: "i8", color: "white"}; car['owner'] = "ibrahim"; // You can add a property:

  • কেস 2:

    var car:any = {type: "BMW", model: "i8", color: "white"}; car.owner = "ibrahim"; // You can set a property: use any type


4

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

this.model = Object.assign(this.model, { newProp: 0 });

3

সতর্কতা নিঃশব্দ করতে আপনি এই ঘোষণাটি যুক্ত করতে পারেন।

declare var obj: any;



3

আপনার পূর্ববর্তী প্রকারটি সংরক্ষণ করতে অস্থায়ীভাবে কোনওটিকে আপনার বস্তুটি কাস্ট করুন

  var obj = {}
  (<any>obj).prop = 5;

নতুন গতিশীল সম্পত্তি তখনই উপলভ্য হবে যখন আপনি কাস্ট ব্যবহার করবেন:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;

3

এখানে একটি বিশেষ সংস্করণ Object.assign, যা প্রতিটি সম্পত্তি পরিবর্তনের সাথে স্বয়ংক্রিয়ভাবে চলক প্রকারটি সামঞ্জস্য করে। অতিরিক্ত ভেরিয়েবল, টাইপ assertions, সুস্পষ্ট ধরনের বা অবজেক্ট কপি প্রয়োজন নেই:

function assign<T, U>(target: T, source: U): asserts target is T & U {
    Object.assign(target, source)
}

const obj = {};
assign(obj, { prop1: "foo" })
//  const obj now has type { prop1: string; }
obj.prop1 // string
assign(obj, { prop2: 42 })
//  const obj now has type { prop1: string; prop2: number; }
obj.prop2 // number

//  const obj: { prop1: "foo", prop2: 42 }

দ্রষ্টব্য: নমুনা টিএস 3.7 আসক্তি ফাংশন ব্যবহার করে । এর রিটার্ন টাইপ assignহয় voidমতো Object.assign


1

আপনি যদি টাইপস্ক্রিপ্ট ব্যবহার করছেন তবে সম্ভবত আপনি প্রকারের সুরক্ষাটি ব্যবহার করতে চান; যে ক্ষেত্রে নগ্ন অবজেক্ট এবং 'যে কোনও' কাউন্টারেন্ডিকেটেড।

অবজেক্ট বা {} ব্যবহার না করাই ভাল তবে কিছু নামযুক্ত টাইপ; অথবা আপনি নির্দিষ্ট ধরণের একটি এপিআই ব্যবহার করতে পারেন যা আপনার নিজের ক্ষেত্রগুলির সাথে প্রসারিত প্রয়োজন। আমি এটি কাজ করতে পেয়েছি:

class Given { ... }  // API specified fields; or maybe it's just Object {}

interface PropAble extends Given {
    props?: string;  // you can cast any Given to this and set .props
    // '?' indicates that the field is optional
}
let g:Given = getTheGivenObject();
(g as PropAble).props = "value for my new field";

// to avoid constantly casting: 
let k:PropAble = getTheGivenObject();
k.props = "value for props";

1

প্রকারান্তরে টাইপসক্রিপ্টে কোনও বস্তুর বৈশিষ্ট্য বরাদ্দ করুন।

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

interface IValue {
    prop1: string;
    prop2: string;
}

interface IType {
    [code: string]: IValue;
}

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

var obj: IType = {};
obj['code1'] = { 
    prop1: 'prop 1 value', 
    prop2: 'prop 2 value' 
};

1
আমি আপনার কোড দিয়ে চেষ্টা করি, তবে আমি কোনও ত্রুটি পাই না: পেস্টবিন.
com

1
attributesভিতরে ক্ষেত্রটি আরম্ভ করার চেষ্টা করুন SomeClass এবং এটি public attributes: IType = {}; পেস্টবিন.
com

1

এটা চেষ্টা কর:

export interface QueryParams {
    page?: number,
    limit?: number,
    name?: string,
    sort?: string,
    direction?: string
}

তারপরে এটি ব্যবহার করুন

const query = {
    name: 'abc'
}
query.page = 1

0

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

আপনি যদি আবশ্যক প্রথমে একটি খালি বস্তুর তৈরি করেন, তারপর এই দুটি সমাধান একটি চয়ন। মনে রাখবেন যে যতবার আপনি ব্যবহার করবেনas, আপনি সুরক্ষা হারাচ্ছেন।

নিরাপদ সমাধান

ধরণ objectহয় নিরাপদ ভিতরে getObject, যার মানে object.aধরনের হতে হবেstring | undefined

interface Example {
  a: string;
  b: number;
}

function getObject() {
  const object: Partial<Example> = {};
  object.a = 'one';
  object.b = 1;
  return object as Example;
}

সংক্ষিপ্ত সমাধান

ধরণ objectহয় নিরাপদ নয় ভিতরে getObject, যার মানে object.aধরনের হতে হবে stringএমনকি তার নিয়োগ আগে।

interface Example {
  a: string;
  b: number;
}

function getObject() {
  const object = {} as Example;
  object.a = 'one';
  object.b = 1;
  return object;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.