টাইপস্ক্রিপ্ট ইন্টারফেস ডিফল্ট মান


137

টাইপস্ক্রিপ্টে আমার নীচের ইন্টারফেস রয়েছে:

interface IX {
    a: string,
    b: any,
    c: AnotherType
}

আমি এই ধরণের একটি ভেরিয়েবল ঘোষণা করি এবং আমি সমস্ত বৈশিষ্ট্য আরম্ভ করি

let x: IX = {
    a: 'abc',
    b: null,
    c: null
}

তারপরে আমি তাদের পরে একটি ডিএন ফাংশনে আসল মান নির্ধারণ করি

x.a = 'xyz'
x.b = 123
x.c = new AnotherType()

তবে আমি প্রতিটি সম্পত্তির জন্য একগুচ্ছ ডিফল্ট নাল মান উল্লেখ করতে পছন্দ করি না যখন বস্তুটি ঘোষণাকালে যখন তারা ঠিক পরে মূল্যবোধে সেট করা যায়। আমি যে বৈশিষ্ট্যগুলি বাতিল করে না তা ডিফল্ট করতে ইন্টারফেসটি বলতে পারি? আমাকে কী করতে দেয়:

let x: IX = {
    a: 'abc'
}

একটি সংকলক ত্রুটি না পেয়ে। এখনই এটি আমাকে বলে

TS2322: টাইপ '{to' 'IX' টাইপ করার যোগ্য নয়। সম্পত্তি 'বি' '{}' টাইপে অনুপস্থিত।


আমি আপনার জন্য দস্তাবেজগুলি যুক্ত করেছি: বাসরত.টাইটবুকস.আইও
— টাইপসক্রিপ্ট

3
আইএমও, উত্তর স্ট্যাকওভারফ্লো.com/a/35074490/129196 এ গ্রহণ করার পদ্ধতি হওয়া উচিত নয়। যদি আপনার সমস্ত সম্পত্তি শুরু করে না রেখে কোনও রাজ্যে কোনও পদ থাকতে পারে এবং এখনও বৈধ হতে পারে, তবে এই উত্তরের দ্বারা নির্দেশিত হিসাবে আপনাকে এই বৈশিষ্ট্যগুলি optionচ্ছিক হিসাবে ঘোষণা করতে হবে: স্ট্যাকওভারফ্লো . com / a / 43226857 / 129196 । অন্যথায় আমরা টাইপস্ক্রিপ্ট (টাইপ সুরক্ষার জন্য) ব্যবহারের একমাত্র উদ্দেশ্য হারাব।
— চার্লস প্রকাশ দাশারি

উত্তর:


98

আমি যে বৈশিষ্ট্যগুলি বাতিল করে না তা ডিফল্ট করতে ইন্টারফেসটি বলতে পারি? কি আমাকে এই করতে দেয়

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

let x: IX = {} as any;

x.a = 'xyz'
x.b = 123
x.c = new AnotherType()

আমি এখানে এবং অন্যান্য নিদর্শনগুলি এখানে নথিভুক্ত করেছি: https://basarat.gitbook.io/typescript/main-1/lazyobjectliteralinitialization


ধন্যবাদ, পূর্বনির্ধারিত মানগুলির
— গুচ্ছকে

42
টাইপ স্ক্রিপ্টের anyউদ্দেশ্যকে ব্যবহার করে । এই অপূর্ণতা ছাড়াও অন্যান্য উত্তর রয়েছে।
— জ্যাক মিলার

অনুরূপ প্রশ্ন সম্পর্কে কিন্তু কেউ জেনেরিকগুলি ব্যবহার করে আমাকে কেউ সহায়তা করতে পারে। এখানে এই প্রশ্নে
— ট্যাব

2
বিস্মিত যে বাসরত 'যে কোনও' উদাহরণ সহকারে যাবে যখন সরবরাহিত লিঙ্কটিতে, তিনি 'লেফু = {F ফু হিসাবে' দিয়ে আরও ভাল বিকল্প সরবরাহ করেন; ('ফু' একটি ইন্টারফেস হচ্ছে)
— নিউরোথুস্ট্রা

1
ওপি একটি টাইপস্ক্রিপ্ট ইন্টারফেস তৈরির সমস্যায় পড়েছে এবং বয়লার ধাতুপট্টাবৃত সমাধানের জন্য জিজ্ঞাসা করছে। আপনার সমাধানটি সম্পূর্ণভাবে ইন্টারফেসগুলি ত্যাগ করতে হবে? পাশাপাশি টাইপস্ক্রিপ্টও এড়িয়ে যাওয়ার পরামর্শ দিতে পারে ...
— মোস পামার

98

আপনি কোনও ইন্টারফেসে ডিফল্ট মান সেট করতে পারবেন না, তবে আপনি Oচ্ছিক বৈশিষ্ট্যগুলি ব্যবহার করে যা করতে চান তা অর্জন করতে পারেন (অনুচ্ছেদ # 3 তুলনা করুন):

https://www.typescriptlang.org/docs/handbook/interfaces.html

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

interface IX {
    a: string,
    b?: any,
    c?: AnotherType
}

তারপরে আপনি এটি করতে পারেন:

let x: IX = {
    a: 'abc'
}

এবং ডিফল্ট মানগুলি নির্ধারণ করতে x.bএবং আপনার x.cযদি সেগুলি সেট না করা থাকে তবে আপনার init ফাংশনটি ব্যবহার করুন ।


3
প্রশ্নে এটি সূচনা করতে x.bএবং x.cসাথে করতে বলা হয়েছিল null। লেখার let x = {a: 'abc'}সময় x.bএবং x.cহ'ল undefined, সুতরাং এই উত্তরটি পুরোপুরি প্রয়োজনীয়তা পূরণ করে না, যদিও এটি একটি স্মার্ট দ্রুত সমাধান।
— বেনি নিউজবাউয়ার

1
@ বেনিনিউজবাউর গৃহীত উত্তরের একই ত্রুটি রয়েছে। এটি সর্বোত্তম উত্তর
— টেল

1
যদি এক্সটি ডিফল্ট মানগুলির সাথে অবজেক্ট হয় তবে চূড়ান্ত উদাহরণ অবজেক্ট তৈরি করা let a: IX = Object.assign({b:true}, x);খ, সি উদাহরণস্বরূপ বস্তুতে
— optionচ্ছিক

ইন্টারফেস ব্যবহারকারীদের সুবিধার্থে বৈশিষ্ট্যগুলিকে "alচ্ছিক" চিহ্নিত করা উচিত নয়। উত্তরটি "না" আপনি "ডিফল্ট সরবরাহের জন্য ইন্টারফেসকে বলতে পারবেন না" তবে ইন্টারফেসের উদাহরণটি শুরু করার জন্য আপনি একটি কারখানা পদ্ধতি সরবরাহ করতে পারেন।
— রিক ও'শায়া

34

যদিও টিমারের উত্তরটি nullডিফল্ট মানগুলির জন্য পুরোপুরি কার্যকর হয় (যার জন্য জিজ্ঞাসা করা হয়েছিল), এখানে আরও একটি সহজ সমাধান যা অন্যান্য ডিফল্ট মানগুলিকে অনুমতি দেয়: একটি বিকল্প ইন্টারফেসের পাশাপাশি ডিফল্টগুলি সমন্বিত ধ্রুবককে সংজ্ঞায়িত করুন; কনস্ট্রাক্টরে সদস্য ভেরিয়েবল সেট করতে স্প্রেড অপারেটরটি ব্যবহার করুনoptions

interface IXOptions {
    a?: string,
    b?: any,
    c?: number
}

const XDefaults: IXOptions = {
    a: "default",
    b: null,
    c: 1
}

export class ClassX {
    private options: IXOptions;

    constructor(XOptions: IXOptions) {
        this.options = { ...XDefaults, ...XOptions };
    }

    public printOptions(): void {
        console.log(this.options.a);
        console.log(this.options.b);
        console.log(this.options.c);
    }
}

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

const x = new ClassX({ a: "set" });
x.printOptions();

আউটপুট:

set
null
1

এই পোষাকটি প্রতিটি ক্ষেত্রে ডিফল্ট সমাধান হিসাবে ব্যবহার করা যায় তবে কিছু ক্ষেত্রে অবশ্যই একটি সৃজনশীল সমাধান হয়। 👍
— অভয় ত্রিপাঠি

যদি মানগুলি কেবল লগ করার পরিবর্তে আমি তাদেরকে কনস্ট ক্যালভ্যালু = এটি.ওপশন.এ * 1000 এর মতো ব্যবহার করতে চাই; এটি এখনও অ্যালার্ম বাড়িয়ে তুলবে কারণ এটি সম্ভাব্য অপরিজ্ঞাত হতে পারে ..
— মণীশ রাওয়াত

হ্যাঁ, আপনি একটি শ্রেণি ব্যবহার করতে পারেন, বা অন্য ভাষায় লিখতে পারেন, যার মধ্যে কোনওটিই তার প্রশ্নের উত্তর দেয় না।
— রিক ও'শায়া

22

আপনি একটি শ্রেণীর সাথে ইন্টারফেসটি বাস্তবায়ন করতে পারেন, তারপরে আপনি নির্মাতার সদস্যদের আরম্ভ করার সাথে মোকাবিলা করতে পারেন:

class IXClass implements IX {
    a: string;
    b: any;
    c: AnotherType;

    constructor(obj: IX);
    constructor(a: string, b: any, c: AnotherType);
    constructor() {
        if (arguments.length == 1) {
            this.a = arguments[0].a;
            this.b = arguments[0].b;
            this.c = arguments[0].c;
        } else {
            this.a = arguments[0];
            this.b = arguments[1];
            this.c = arguments[2];
        }
    }
}

অন্য পদ্ধতির একটি কারখানার ফাংশন ব্যবহার করা হয়:

function ixFactory(a: string, b: any, c: AnotherType): IX {
    return {
        a: a,
        b: b,
        c: c
    }
}

তারপরে আপনি কেবল:

var ix: IX = null;
...

ix = new IXClass(...);
// or
ix = ixFactory(...);

4

Partialডকুমেন্টেশনে বর্ণিত ম্যাপযুক্ত প্রকারটি আপনি ব্যবহার করতে পারেন : https://www.typescriptlang.org/docs/handbook/release-notes/tyypecript-2-1.html

আপনার উদাহরণে, আপনি পাবেন:

interface IX {
    a: string;
    b: any;
    c: AnotherType;
}

let x: Partial<IX> = {
    a: 'abc'
}

যদি এক্স ডিফল্ট মানগুলির সাথে অবজেক্ট হয় তবে চূড়ান্ত ইনস্ট্যান্স অবজেক্ট তৈরি করা let a: IX = Object.assign({b:true}, x);ত্রুটির কারণ হতে পারেPartial<IX> cannot be assigned to IX
— লাক্যলুক

আংশিক টাইপ পরিবর্তন করে। xআর প্রয়োগ করে না IX, তবে একটি আংশিক IX। Partialএমন জায়গাগুলির জন্য ভাল যেখানে প্রতিটি সম্পত্তি alচ্ছিক হতে পারে, উদাহরণস্বরূপ একটি ওআরএম সহ, যেখানে আপনি কোনও অবজেক্ট ইন্টারফেসের একটি আংশিক পাস করতে পারেন এবং কেবলমাত্র সেই ক্ষেত্রগুলিই সংজ্ঞায়িত করতে পারেন ( undefinedযার বিপরীতে একটি প্রতিটি ক্ষেত্রই Partialহতে পারে)। ডিফল্ট মান সহ ক্ষেত্রগুলি রয়েছে এমন ইন্টারফেসগুলির জন্য, আপনি let x: Partial<IX> = { /* non-default fields */ } as IXসিনট্যাক্স ব্যবহার করে ডিফল্ট মানগুলি ঘোষণা না করেই এই জাতীয় ইন্টারফেস প্রয়োগকারী অবজেক্ট ল্যাটারালগুলি ঘোষণা করতে পারেন ।
— পল-সেবাস্তিয়ান মানোলে

1

আমি যা পৌঁছেছিলাম তার চেয়ে ভালতর উপায় খুঁজতে গিয়ে আমি হোঁচট খেয়েছি। উত্তরগুলি পড়ে এবং সেগুলি চেষ্টা করে দেখে আমি ভেবেছিলাম যে আমি যা করছি তা পোস্ট করা ভাল কারণ অন্য উত্তরগুলি আমার পক্ষে সংক্ষিপ্ততা বোধ করে না। আমি যখনই একটি নতুন ইন্টারফেস সেটআপ করি তখন কেবলমাত্র একটি সংক্ষিপ্ত পরিমাণ কোড লিখতে হবে তা আমার পক্ষে গুরুত্বপূর্ণ ছিল। আমি স্থির ...

একটি কাস্টম জেনেরিক ডিপকপি ফাংশন ব্যবহার করে:

deepCopy = <T extends {}>(input: any): T => {
  return JSON.parse(JSON.stringify(input));
};

আপনার ইন্টারফেস সংজ্ঞায়িত করুন

interface IX {
    a: string;
    b: any;
    c: AnotherType;
}

... এবং পৃথক কনস্টে ডিফল্টগুলি সংজ্ঞায়িত করুন।

const XDef : IX = {
    a: '',
    b: null,
    c: null,
};

তারপরে এইভাবে আরম্ভ করুন:

let x : IX = deepCopy(XDef);

এটাই দরকার ..

.. যাহোক ..

আপনি যদি কোনও মূল উপাদানকে কাস্টম করতে চান তবে কাস্টম ডিফল্ট মানগুলি গ্রহণ করতে আপনি ডিপকপি ফাংশনটি সংশোধন করতে পারেন। ফাংশনটি হয়ে যায়:

deepCopyAssign = <T extends {}>(input: any, rootOverwrites?: any): T => {
  return JSON.parse(JSON.stringify({ ...input, ...rootOverwrites }));
};

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

let x : IX = deepCopyAssign(XDef, { a:'customInitValue' } );

গভীর অনুলিপির অন্য কোনও পছন্দসই পদ্ধতি কাজ করবে। যদি কেবল অগভীর অনুলিপি প্রয়োজন হয় তবে অবজেক্ট.সেসাইন যথেষ্ট হবে, ইউটিলিটি deepCopyবা deepCopyAssignফাংশনটির প্রয়োজনীয়তা বাদ দিয়ে ।

let x : IX = object.assign({}, XDef, { a:'customInitValue' });

জ্ঞাত সমস্যা

  • এটি এই ছদ্মবেশে গভীরভাবে নির্ধারিত হবে না তবে deepCopyAssignনিয়োগের আগে পুনরাবৃত্তি এবং প্রকারগুলি পরীক্ষা করে পরিবর্তন করা খুব কঠিন নয় ।
  • পার্স / স্ট্রিংফাই প্রক্রিয়া দ্বারা কার্য এবং রেফারেন্সগুলি হারিয়ে যাবে। আমার কাজের জন্য আমার সেগুলির দরকার নেই এবং ওপিও করেনি।
  • কাস্টম আরম্ভের মানগুলি আইডিই দ্বারা ইঙ্গিত দেওয়া হয় না বা সম্পাদিত হলে পরীক্ষিত টাইপ হয় না।

0

আমার সমাধান:

টাইপিংয়ের সমস্যাগুলি ঠিক করার জন্য আমি অবজেক্ট.সেসাইন এর উপরে মোড়ক তৈরি করেছি।

export function assign<T>(...args: T[] | Partial<T>[]): T {
  return Object.assign.apply(Object, [{}, ...args]);
}

ব্যবহার:

env.base.ts

export interface EnvironmentValues {
export interface EnvironmentValues {
  isBrowser: boolean;
  apiURL: string;
}

export const enviromentBaseValues: Partial<EnvironmentValues> = {
  isBrowser: typeof window !== 'undefined',
};

export default enviromentBaseValues;

env.dev.ts

import { EnvironmentValues, enviromentBaseValues } from './env.base';
import { assign } from '../utilities';

export const enviromentDevValues: EnvironmentValues = assign<EnvironmentValues>(
  {
    apiURL: '/api',
  },
  enviromentBaseValues
);

export default enviromentDevValues;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.