টাইপস্ক্রিপ্টে বস্তুর আক্ষরিক ক্ষেত্রে সংজ্ঞা টাইপ করুন


344

টাইপস্ক্রিপ্ট ক্লাসে বৈশিষ্ট্যগুলির জন্য প্রকারগুলি ঘোষণা করা সম্ভব, উদাহরণস্বরূপ:

class className {
  property: string;
};

আক্ষরিক অর্থে কোনও সম্পত্তির ধরণ কীভাবে ঘোষণা করবেন?

আমি নিম্নলিখিত কোড চেষ্টা করেছি কিন্তু এটি সংকলন করে না:

var obj = {
  property: string;
};

আমি নিম্নলিখিত ত্রুটি পাচ্ছি:

'স্ট্রিং' নামটি বর্তমান সুযোগে নেই does

আমি কি কিছু ভুল করছি বা এটি একটি বাগ?

উত্তর:


423

আপনি খুব কাছাকাছি, আপনি কেবল =একটি সঙ্গে প্রতিস্থাপন প্রয়োজন :। আপনি কোনও অবজেক্ট টাইপের আক্ষরিক ব্যবহার করতে পারেন (স্পেক বিভাগটি 3.5.3 দেখুন) বা একটি ইন্টারফেস। একটি অবজেক্ট টাইপের আক্ষরিক ব্যবহার আপনার কাছে যা রয়েছে তার কাছাকাছি:

var obj: { property: string; } = { property: "foo" };

তবে আপনি একটি ইন্টারফেসও ব্যবহার করতে পারেন

interface MyObjLayout {
    property: string;
}

var obj: MyObjLayout = { property: "foo" };

14
কাস্ট অপারেটরের সাথে @ রিক লাভের ডিআরওয়াই (নিজেকে পুনরাবৃত্তি করবেন না) বিকল্পটি অনেকটা সুন্দর বলে মনে হচ্ছে। খালি মন্তব্য করা হচ্ছে, নিম্নমানের নয় ...
স্পেফটার

আমি জানি এটির কিছুক্ষণ আগে জবাব দেওয়া হয়েছিল, কিন্তু ক্লাসের পদ্ধতিগুলির পাশাপাশি বৈশিষ্ট্যগুলি থাকলে সমস্যাগুলি উত্থাপিত হতে পারে এমন অনুমানগুলিতে আমি কি ভুল করছি? যেহেতু ক্লাসটি আরম্ভ হয় না এবং আমরা কেবল সম্পত্তি বরাদ্দ করি তাই ক্লাসে কোনও পদ্ধতি কল করা একটি নাল ব্যতিক্রম ঘটায়। মূলত, আমরা যে অবজেক্টটি তৈরি করি তা ক্লাস হিসাবে কেবল 'কাজ করে' কারণ আমরা এর ধরণ নির্ধারণ করি, তবে এটি আসলে that শ্রেণীর উদাহরণ নয়। অর্থাৎ আমাদের 'নতুন' কীওয়ার্ড দিয়ে ক্লাস তৈরি করা দরকার। এবং আমরা তখন স্কোয়ার 1 এ ফিরে আসছি, যেহেতু আমরা নতুন শ্রেণি () {প্রপ: 1 like এর মতো কিছু করতে পারি না; টিএসে যেমন আমরা সি # তে পারি, উদাহরণস্বরূপ।
DeuxAlpha

@ ডেক্সআল্ফা এটি একটি ইন্টারফেসে বরাদ্দ দিচ্ছে , যার কোনও পদ্ধতি থাকতে পারে না। আমি বিশ্বাস করি না যে আপনি এই জাতীয় ক্লাসে অর্পণ করতে পারেন।
মোগ0


@ ডেক্সআল্ফা এটি কোনও শ্রেণীর অবজেক্ট নয়, একটি আক্ষরিক বস্তু তৈরি করছে। এছাড়াও একটি ইন্টারফেসের পদ্ধতি থাকতে পারে। যদি আপনার ইন্টারফেস কোনও পদ্ধতি সংজ্ঞায়িত করে, তবে বস্তুর আক্ষরিক অবশ্যই এটি সংজ্ঞায়িত করতে হবে - এটি নਾਲ হবে না n ইন্টারফেসটি সংজ্ঞায়িত করে বা টাইপ সিস্টেমটি একটি ত্রুটি প্রদর্শন করবে এমন বস্তুর আক্ষরিক অবশ্যই আবশ্যক everything
রিক লাভ

291

2019-05-15 আপডেট করুন (বিকল্প হিসাবে উন্নত কোড প্যাটার্ন)

ব্যবহার করার বহু বছর পরে constআরও কার্যকরী কোড এবং উপকৃত , আমি বেশিরভাগ ক্ষেত্রে নীচে ব্যবহার করার বিরুদ্ধে সুপারিশ করব। (অবজেক্ট তৈরি করার সময়, টাইপ সিস্টেমটিকে কোনও নির্দিষ্ট ধরণের পরিবর্তে টাইপ করার পরিবর্তে টাইপ সিস্টেমকে জোর করা প্রায়শই কিছু ভুল হওয়ার ইঙ্গিত দেয়)।

পরিবর্তে আমি constযতটা সম্ভব ভেরিয়েবলগুলি ব্যবহার করার পরামর্শ দেব এবং তারপরে অবজেক্টটি চূড়ান্ত পদক্ষেপ হিসাবে রচনা করব:

const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
  • এটি সুস্পষ্ট টাইপিংয়ের কোনও প্রয়োজন ছাড়াই সবকিছু সঠিকভাবে টাইপ করবে।
  • মাঠের নামগুলি পুনরায় টাইপ করার দরকার নেই।
  • এটি আমার অভিজ্ঞতা থেকে সবচেয়ে পরিষ্কার কোডের দিকে নিয়ে যায়।
  • এটি কম্পাইলারকে আরও রাষ্ট্রীয় যাচাইকরণ সরবরাহ করতে দেয় (উদাহরণস্বরূপ, আপনি যদি একাধিক স্থানে ফিরে যান তবে সংকলকটি একই ধরণের অবজেক্টটি সর্বদা ফিরে আসার বিষয়টি নিশ্চিত করবে - যা আপনাকে প্রতিটি অবস্থানে পুরো রিটার্ন মান ঘোষণা করতে উত্সাহ দেয় - পুরোপুরি পরিষ্কার করে যে মান অভিপ্রায়)।

সংযোজন 2020-02-26

আপনার যদি এমন কোনও ধরণের প্রয়োজন হয় যা আপনাকে অলসভাবে শুরু করা যেতে পারে: চিহ্নিত করুন এটি একটি নাল যুক্ত ইউনিয়ন (নাল বা প্রকার)। টাইপ সিস্টেমটি আপনাকে প্রথমে এর কোনও মান রয়েছে তা নিশ্চিত না করে এটি ব্যবহার করতে বাধা দেবে।

ইন tsconfig.json, আপনি কঠোর নাল চেক সক্ষম করেছেন তা নিশ্চিত করুন:

"strictNullChecks": true

তারপরে এই প্যাটার্নটি ব্যবহার করুন এবং টাইপ সিস্টেমটিকে আপনাকে দুর্ঘটনাজনক নাল / অপরিজ্ঞাত অ্যাক্সেস থেকে রক্ষা করার অনুমতি দিন:



const state = {
    instance: null as null | ApiService,
    // OR
    // instance: undefined as undefined | ApiService,

};

const useApi = () => {
    // If I try to use it here, the type system requires a safe way to access it

    // Simple lazy-initialization 
    const api = state?.instance ?? (state.instance = new ApiService());
    api.fun();

    // Also here are some ways to only access it if it has value:

    // The 'right' way: Typescript 3.7 required
    state.instance?.fun();

    // Or the old way: If you are stuck before Typescript 3.7
    state.instance && state.instance.fun();

    // Or the long winded way because the above just feels weird
    if (state.instance) { state.instance.fun(); }

    // Or the I came from C and can't check for nulls like they are booleans way
    if (state.instance != null) { state.instance.fun(); }

    // Or the I came from C and can't check for nulls like they are booleans 
    // AND I was told to always use triple === in javascript even with null checks way
    if (state.instance !== null && state.instance !== undefined) { state.instance.fun(); }
};

class ApiService {
    fun() {
        // Do something useful here
    }
}

99% ক্ষেত্রে নীচেরটি করবেন না:

আপডেট 2016-02-10 - টিএসএক্স পরিচালনা করতে (ধন্যবাদ জোশ)

asটিএসএক্সের জন্য অপারেটরটি ব্যবহার করুন ।

var obj = {
    property: null as string
};

একটি দীর্ঘ উদাহরণ:

var call = {
    hasStarted: null as boolean,
    hasFinished: null as boolean,
    id: null as number,
};

আসল উত্তর

এই সংযোগটি তৈরি করতে কাস্ট অপারেটরটি ব্যবহার করুন (পছন্দসই ধরণের নাল কাস্ট করে)।

var obj = {
    property: <string> null
};

একটি দীর্ঘ উদাহরণ:

var call = {
    hasStarted: <boolean> null,
    hasFinished: <boolean> null,
    id: <number> null,
};

এটি দুটি অংশ থাকার চেয়ে অনেক ভাল (একটি প্রকার ঘোষণা করার জন্য, দ্বিতীয়টি খেলাপি হিসাবে ঘোষণা করা):

var callVerbose: {
    hasStarted: boolean;
    hasFinished: boolean;
    id: number;
} = {
    hasStarted: null,
    hasFinished: null,
    id: null,
};

10
আপনি যদি টিএসএক্স (জেএসএক্সের সাথে টিএস) ব্যবহার করছেন, আপনি কোণ বন্ধনী নামকরণ ব্যবহার করতে পারবেন না, সুতরাং সেই লাইনগুলি এমন কিছুতে পরিণত হয় property: null as stringযেখানে গুরুত্বপূর্ণ পার্থক্যটি asঅপারেটর।
জোশ

2
@ রিকলভ এটিতে কী বস্তুর ভেরিয়েবলের ধরণটি আসলেই সীমাবদ্ধ করে না, বা যখন দায়িত্ব অর্পণ করা হয় তখন কেবল প্রকারগুলি নির্দিষ্ট করার উপায়? অন্য কথায়, callআপনার দ্বিতীয় উদাহরণে ভেরিয়েবলটি নির্ধারণের পরে, আপনি কি একে সম্পূর্ণ ভিন্ন ধরণের বরাদ্দ করতে পারেন?
ড্যানিয়েল গ্রিসকম

3
এটি উত্তর হওয়া উচিত
ড্রয় আর

4
কাজ করছে না. Error:(33, 15) TS2352:Type 'null' cannot be converted to type 'string'.
স্লাইডশোপ 2

2
এটি কি ভাষার কোনও বৈশিষ্ট্যের অপব্যবহার বা এটি আসলে লেজিট? আপনি কি অফিশিয়াল ডক্সে মুর পড়ার জন্য লিঙ্ক সরবরাহ করতে পারেন? ধন্যবাদ!
কিওয়ার্টি

31

আমি অবাক হয়েছি যে কারও এটির কথা উল্লেখ করা হয়নি তবে আপনি কেবল একটি ইন্টারফেস তৈরি করতে পারেন ObjectLiteralযা এই key: valueধরণের জোড়া গ্রহণ করে string: any:

interface ObjectLiteral {
  [key: string]: any;
}

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

let data: ObjectLiteral = {
  hello: "world",
  goodbye: 1,
  // ...
};

একটি যুক্ত বোনাস হ'ল আপনি নিজের পছন্দমতো যতগুলি অবজেক্ট চান তার প্রয়োজনে আপনি এই ইন্টারফেসটি অনেকবার পুনরায় ব্যবহার করতে পারবেন।

শুভকামনা।


3
এটি একটি খারাপ ধারণা, এটি টাইপ সিস্টেমকে অকেজো করে তোলে। টাইপস্ক্রিপ্টের মূল বিষয়টি হ'ল টাইপ সিস্টেমটিকে ত্রুটিগুলি রোধ করতে সহায়তা করার পাশাপাশি সরঞ্জামাদিকরণের ক্ষেত্রে আরও ভাল স্ব-পরিপূরণ কার্যকারিতা সরবরাহ করতে সহায়তা করা - এটি মূলত টাইপস্ক্রিপ্টের সমস্ত সুবিধা অক্ষম করে। উপরের উদাহরণে কোনও ইন্টারফেস ব্যবহার না করা ভাল be
রিক লাভ

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

@ সিপিএইচপিথন কেন তাদের নির্দিষ্ট ধরণের সাথে কেবল alচ্ছিক পরামিতিগুলি নির্দিষ্ট করে না? কোডগুলি সময় নামগুলি না জানা থাকলে (কেবলমাত্র তারা কোনও ডাটাবেস বা বাহ্যিক উত্স থেকে আসছে) এটি কেবলমাত্র তখনই বোঝা যাবে। যুক্তিগুলির জটিল সংমিশ্রণের জন্যও ইউনিয়নের ধরণগুলি দুর্দান্ত কাজ করে। আপনি যদি নির্দিষ্ট নামের সাথে কোডিং করে থাকেন তবে যদি সম্ভব হয় তবে এগুলি সংজ্ঞায়িত করা উচিত। যদি এটি কেবলমাত্র ডেটা যা যুক্তি প্রভাবিত করে না তবে অবশ্যই এটি টাইপ সিস্টেম থেকে ছেড়ে দিন।
রিক লাভ

1
@ রিকলভ "কোডের সময় নামগুলি জানা যায় না" -> এটি একটি ভাল এবং ব্যবহারিক উদাহরণ, এই কীগুলির ধরণের মানগুলি জানা যায় এবং সেগুলি সমস্ত একই (যেমন স্ট্রিং )। মনে রাখবেন যে আমি কেবল সেই [key: string]অংশটির ব্যবহারের পক্ষে ছিলাম , কোনও অংশকেই মূল্যের ধরণের সংজ্ঞা হিসাবে দেখিনি ... এটি প্রকৃতপক্ষে প্রকারের উপযোগিতাটি গ্রহণ করবে।
সিপিএইচপিথন

1
আমি স্ট্রিং এবং সংখ্যা যুক্ত করার অনুমতি চাইলেও অন্যান্য ধরণের না করে কীভাবে যাব?
গাধাবানানা

14

যদি আপনি কোনও প্রকার টিকা লিখতে চেষ্টা করেন তবে বাক্য গঠনটি হ'ল:

var x: { property: string; } = ...;

আপনি যদি কোনও বস্তু আক্ষরিক লেখার চেষ্টা করছেন তবে বাক্য গঠনটি হ'ল:

var x = { property: 'hello' };

আপনার কোডটি একটি মান অবস্থানে কোনও প্রকারের নাম ব্যবহার করার চেষ্টা করছে।


10
তোমার var x: { property: string; } = ...;তো একটা জ্বালাতন! আমি আশা ঊহ্য শব্দ বৈধ সিনট্যাক্স সাধারণভাবে সংক্ষেপে জন্য হতে ছিল var x: { property: string; } = { property: 'hello' };
জেসন ক্লেবান

10

টাইপস্ক্রিপ্টে যদি আমরা অবজেক্টটি ঘোষণা করি তবে আমরা নিম্নলিখিত বাক্য গঠনটি ব্যবহার করব:

[access modifier] variable name : { /* structure of object */ }

উদাহরণ স্বরূপ:

private Object:{ Key1: string, Key2: number }

7

আপনি যদি একটি থেকে typings যোগ করার চেষ্টা করছেন তবে destructured একটি ফাংশন আর্গুমেন্ট বস্তুর আক্ষরিক, উদাহরণস্বরূপ, সিনট্যাক্স হল:

function foo({ bar, baz }: { bar: boolean, baz: string }) {
  // ...
}

foo({ bar: true, baz: 'lorem ipsum' });

5

আপনার বৈশিষ্ট্যগুলির যদি একই ধরণ থাকে তবে আপনি পূর্বনির্ধারিত ইউটিলিটি ধরণটি ব্যবহার করতে পারেন Record:

type Keys = "property" | "property2"

var obj: Record<Keys, string> = {
  property: "my first prop",
  property2: "my second prop",
};

আপনি অবশ্যই আরও যেতে পারেন এবং আপনার সম্পত্তি মানগুলির জন্য একটি পছন্দসই ধরণের সংজ্ঞা দিতে পারেন:

type Keys = "property" | "property2"
type Value = "my prop" | "my other allowed prop"

var obj: Record<Keys, Value> = {
  property: "my prop",
  property2: "my second prop", // TS Error: Type '"my second prop"' is not assignable to type 'Value'.
};

2
ঠিক আমার যা প্রয়োজন ছিল। ধন্যবাদ! জয়ের জন্য টাইপস্ক্রিপ্ট!
অডাসিটাস

আমি এখানে letপরিবর্তে ব্যবহার করব var
Fwd079

3
// Use ..

const Per = {
  name: 'HAMZA',
  age: 20,
  coords: {
    tele: '09',
    lan: '190'
  },
  setAge(age: Number): void {
    this.age = age;
  },
  getAge(): Number {
    return age;
  }
};
const { age, name }: { age: Number; name: String } = Per;
const {
  coords: { tele, lan }
}: { coords: { tele: String; lan: String } } = Per;

console.log(Per.getAge());

3
আরে এবং তাই আপনাকে স্বাগতম! আপনি কীভাবে আপনার উত্তরটি প্রসারিত করতে পারেন, এটি কীভাবে / কেন কাজ করে তা ব্যাখ্যা করা সহায়ক।
পার্টি-রিং

1

আপনার কোডে:

var obj = {
  myProp: string;
};

আপনি আসলে একটি বস্তু আক্ষরিক তৈরি করছেন এবং সম্পত্তি মাইপ্রপকে পরিবর্তনশীল স্ট্রিং বরাদ্দ করছেন। যদিও খুব খারাপ অনুশীলন এটি আসলে বৈধ টিএস কোড হবে (এটি ব্যবহার করবেন না!):

var string = 'A string';

var obj = {
  property: string
};

যাইহোক, আপনি যা চান তা অবজেক্ট আক্ষরিক টাইপ করা হয়েছে। এটি বিভিন্ন উপায়ে অর্জিত হতে পারে:

ইন্টারফেস:

interface myObj {
    property: string;
}

var obj: myObj = { property: "My string" };

কাস্টম প্রকার:

type myObjType = {
    property: string
};

var obj: myObjType = { property: "My string" };

কাস্ট অপারেটর:

var obj = {
    myString: <string> 'hi',
    myNumber: <number> 132,
};

আক্ষরিক বস্তুর ধরণ:

var obj: { property: string; } = { property: "Mystring" };
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.