ওভাররাইডিং ইন্টারফেস সম্পত্তি প্রকার টাইপস্ক্রিপ্ট d.ts ফাইল মধ্যে সংজ্ঞায়িত


128

কোনও টাইপ *.d.tsস্ক্রিপ্টে সংজ্ঞায়িত ইন্টারফেসের ধরণের ধরণের পরিবর্তন করার কোনও উপায় আছে কি ?

উদাহরণস্বরূপ: একটি ইন্টারফেস x.d.tsহিসাবে সংজ্ঞায়িত করা হয়

interface A {
  property: number;
}

আমি যে টাইপস্ক্রিপ্ট ফাইলগুলিতে লিখি তা এটিকে পরিবর্তন করতে চাই

interface A {
  property: Object;
}

বা এমনকি এটি কাজ করবে

interface B extends A {
  property: Object;
}

এই পদ্ধতির কাজ করবে? আমি যখন আমার সিস্টেমে চেষ্টা করেছি তখন এটি কাজ করে না। শুধু এটি সম্ভব কিনা তা নিশ্চিত করতে চান?

উত্তর:


56

আপনি বিদ্যমান সম্পত্তির ধরণটি পরিবর্তন করতে পারবেন না।

আপনি একটি সম্পত্তি যুক্ত করতে পারেন:

interface A {
    newProperty: any;
}

তবে বিদ্যমান এক ধরণের পরিবর্তন:

interface A {
    property: any;
}

একটি ত্রুটির ফলাফল:

পরবর্তী পরিবর্তনশীল ঘোষণার অবশ্যই একই ধরণের থাকতে হবে। পরিবর্তনশীল 'সম্পত্তি' অবশ্যই 'সংখ্যা' টাইপের হতে হবে, তবে এখানে 'কোনও' টাইপ রয়েছে

আপনার অবশ্যই নিজস্ব ইন্টারফেস থাকতে পারে যা বিদ্যমানটির প্রসারিত করে। সেক্ষেত্রে আপনি কোনও প্রকারটি কেবলমাত্র একটি সামঞ্জস্যপূর্ণ টাইপকে ওভাররাইড করতে পারেন, উদাহরণস্বরূপ:

interface A {
    x: string | number;
}

interface B extends A {
    x: number;
}

যাইহোক, আপনার সম্ভবত Objectএকটি প্রকার হিসাবে ব্যবহার এড়ানো উচিত , পরিবর্তে প্রকারটি ব্যবহার করুন any

ইন এর জন্য দস্তাবেজ anyটাইপ এটা বলে:

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

let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

টাইপস্ক্রিপ্ট> = 1.1 এর সাথে ইন্টারফেস প্রসারিত করে ধরণের পদ্ধতির ওভাররাইট করতে আপনাকে মূল ইন্টারফেস থেকে সমস্ত পদ্ধতি অন্তর্ভুক্ত করতে হবে, অন্যথায় আপনি ত্রুটি পাবেন যে প্রকারগুলি বেমানান রয়েছে github.com/Mic Microsoft
TypeScript/

আপনি প্রথমে ওভাররাইট করতে চান এমন মানগুলিকে ছাড়িয়ে দিতে পারেন এবং সেগুলি পুনরায় সংজ্ঞায়িত করতে পারেন, আমরা কি @ZSkycat এর উত্তরটি সমাধান করতে পারি?
zeachco


@ ডাব্লুভিডিজেড নয় যে আমি ডাউনটা সম্পর্কে খুব বেশি যত্নশীল, তবে আপনি কী সম্পর্কে কথা বলছেন? এমনকি কেউ কোথায় জাভা উল্লেখ করেছেন? "জাভা" এর জন্য পৃষ্ঠাটি অনুসন্ধান করার জন্য কেবল একটির সন্ধান রয়েছে এবং এটি আপনার মন্তব্যে রয়েছে।
নিতজান টোমার

সম্ভবত আমি কিছুটা কৃপণ হয়ে পড়েছিলাম তবে এটি আমাকে কিছুটা বিরক্ত করেছিল যে আপনি "অন্যান্য ভাষাগুলি" বলেছিলেন যখন আপনি ঠিক জাভা-তে যেমন বলতে পারতেন। বা অন্যান্য অনেক ভাষা আছে যা সর্বজনীন বেস বর্গ হিসাবে অবজেক্ট আছে? আমি সি # সম্পর্কে জানি, তবে অবশ্যই সি # জাভা দ্বারা অনুপ্রাণিত হয়েছিল।
wvdz

232

আমি একটি পদ্ধতি ব্যবহার করি যা প্রথমে ক্ষেত্রগুলি ফিল্টার করে এবং তারপরে তাদের একত্রিত করে।

রেফারেন্স ধরণ থেকে সম্পত্তি বাদ দিন

interface A {
    x: string
}

export type B = Omit<A, 'x'> & { x: number };

ইন্টারফেসের জন্য:

interface A {
    x: string
}

interface B extends Omit<A, 'x'> {
  x: number
}

4
এটি জানতে পেরে দুর্দান্ত। তবে সমস্যাটি হ'ল এটি এখনও বিদ্যমানটি সংশোধন করছে না।
ফ্রিউইন্ড

10
আমি যা খুঁজছিলাম ঠিক এটাই ছিল। আমি টাইপস্ক্রিপ্টটি extendডিফল্টরূপে কীভাবে কাজ করবে বলে প্রত্যাশা করেছিলাম , কিন্তু হায়, এই সামান্য কিছুটা Omitঠিক করে দেয় 🙌
ডসন বি

4
ইন্টারফেসটি প্রসারিত করা ঠিক আমি যা খুঁজছিলাম, ধন্যবাদ!
mhodges

4
দ্রষ্টব্য: এটি ব্যবহার করার জন্য আপনার উপরে টাইপস্ক্রিপ্টের 3.5.3 প্রয়োজন হবে।
ভিকসন

93
type ModifiedType = Modify<OriginalType, {
  a: number;
  b: number;
}>

interface ModifiedInterface extends Modify<OriginalType, {
  a: number;
  b: number;
}> {}

জেডস্কাইকাটের extends Omit সমাধান থেকে অনুপ্রাণিত হয়ে আমি এটি নিয়ে এসেছি:

type Modify<T, R> = Omit<T, keyof R> & R;

// before typescript@3.5
type Modify<T, R> = Pick<T, Exclude<keyof T, keyof R>> & R

উদাহরণ:

interface OriginalInterface {
  a: string;
  b: boolean;
  c: number;
}

type ModifiedType  = Modify<OriginalInterface , {
  a: number;
  b: number;
}>

// ModifiedType = { a: number; b: number; c: number; }

ধাপে ধাপে:

type R0 = Omit<OriginalType, 'a' | 'b'>        // { c: number; }
type R1 = R0 & {a: number, b: number }         // { a: number; b: number; c: number; }

type T0 = Exclude<'a' | 'b' | 'c' , 'a' | 'b'> // 'c'
type T1 = Pick<OriginalType, T0>               // { c: number; }
type T2 = T1 & {a: number, b: number }         // { a: number; b: number; c: number; }

প্রকারের স্ক্রিপ্ট ইউটিলিটি প্রকার


9
এটি একটি দুর্দান্ত সমাধান।
অস্টিন ব্রুনখারস্ট

4
এখানে নুব কিন্তু আপনি একটি ইন্টারফেস থেকে আপনার উদাহরণ নং একটি টাইপ পরিবর্তন? নাকি কোনও পার্থক্য নেই?
ডমিনিক

নিসেইইআইইইই: ডি
সাঁইকিওও

4
@ ডমিনিক গুড পয়েন্ট, আমি উত্তর আপডেট করেছি। একই নামের দুটি ইন্টারফেস একীভূত করতে পারে। টাইপসস্ক্রিপ্ট.অর্গ.ওডোকস
কিওয়ার্টি

35

@ ZSkycat এর উত্তরটি সামান্য প্রসারিত করে আপনি একটি জেনেরিক তৈরি করতে পারেন যা দুটি অবজেক্টের ধরণ গ্রহণ করে এবং প্রথমটির সদস্যদের ওভাররাইড করে দ্বিতীয় সদস্যদের সাথে একীভূত প্রকারটি প্রদান করে।

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;

interface A {
    name: string;
    color?: string;
}

// redefine name to be string | number
type B = Merge<A, {
    name: string | number;
    favorite?: boolean;
}>;

let one: A = {
    name: 'asdf',
    color: 'blue'
};

// A can become B because the types are all compatible
let two: B = one;

let three: B = {
    name: 1
};

three.name = 'Bee';
three.favorite = true;
three.color = 'green';

// B cannot become A because the type of name (string | number) isn't compatible
// with A even though the value is a string
// Error: Type {...} is not assignable to type A
let four: A = three;

4
খুব দুর্দান্ত :-) আমি ওমিটের সাথে এক বা দুটি বৈশিষ্ট্য নিয়ে এটি আগে করেছি, তবে এটি অনেক শীতল :-) আমি প্রায়শই একটি সার্ভার সত্তার প্রকারটি 'প্রসারিত' করতে এবং ক্লায়েন্টের জন্য প্রয়োজনীয় বা optionচ্ছিক কিছু জিনিস পরিবর্তন করতে চাই ।
সাইমন_উইভার

4
এটি এখন গ্রহণযোগ্য সমাধান হওয়া উচিত। একটি ইন্টারফেস "প্রসারিত" করার সবচেয়ে সহজ উপায়।
manuhortet

12

Omit ইন্টারফেস প্রসারিত করার সময় সম্পত্তি:

interface A {
  a: number;
  b: number;
}

interface B extends Omit<A, 'a'> {
  a: boolean;
}

3

মজার বিষয় আমি একই মামলার সমাধানের সম্ভাবনা তদন্ত করতে ব্যয় করি। আমি দেখেছি যে এভাবে করা সম্ভব নয়:

// a.ts - module
export interface A {
    x: string | any;
}

// b.ts - module
import {A} from './a';

type SomeOtherType = {
  coolStuff: number
}

interface B extends A {
    x: SomeOtherType;
}

কারণ কোনও মডিউল আপনার অ্যাপ্লিকেশনে উপলব্ধ সমস্ত ধরণের সম্পর্কে জানতে পারে না। এবং এটি বেশ বিরক্তিকর বন্দর সবকিছু থেকে এবং এই জাতীয় কোড করছে doing

export interface A {
    x: A | B | C | D ... Million Types Later
}

স্বয়ংক্রিয়রূপে ভাল কাজ করতে আপনাকে পরে ধরণের সংজ্ঞা দিতে হবে।


সুতরাং আপনি কিছুটা প্রতারণা করতে পারেন:

// a.ts - module
export interface A {
    x: string;
}

ডিফল্টরূপে কিছু প্রকারটি রেখে দিন, যখন স্বতঃপূরণ কাজ করতে দেয়, যখন ওভাররাইডগুলি প্রয়োজন হয় না।

তারপরে

// b.ts - module
import {A} from './a';

type SomeOtherType = {
  coolStuff: number
}

// @ts-ignore
interface B extends A {
    x: SomeOtherType;
}

@ts-ignoreপতাকা ব্যবহার করে বোকা ব্যতিক্রমগুলি এখানে অক্ষম করুন , আমাদের বলছেন যে আমরা কিছু ভুল করছি। এবং মজার বিষয় সবকিছু প্রত্যাশার মতো কাজ করে।

আমার ক্ষেত্রে আমি প্রকারের স্কোপ xভিশনটিকে হ্রাস করছি , এটি আমাকে কোডটি আরও কঠোর করার অনুমতি দেয়। উদাহরণস্বরূপ বোকা পরিস্থিতি এড়াতে আপনার 100 টি বৈশিষ্ট্যের তালিকা রয়েছে এবং আপনি এটি 10 ​​এ কমিয়ে আনুন


3

সম্পত্তির প্রকার সংকীর্ণ করার জন্য extend, নিতজানের উত্তরে যেমন সরল কাজ নির্ভুল হয় :

interface A {
    x: string | number;
}

interface B extends A {
    x: number;
}

প্রসারিত করার জন্য, বা টাইপটিকে সাধারণভাবে ওভাররাইড করার জন্য, আপনি Zskycat এর সমাধান করতে পারেন :

interface A {
    x: string
}

export type B = Omit<A, 'x'> & { x: number };

তবে, যদি আপনার ইন্টারফেসটি Aকোনও সাধারণ ইন্টারফেস প্রসারিত করে, আপনি ব্যবহার করার সময় কাস্টম ধরণের Aঅবশিষ্ট প্রকারের বৈশিষ্ট্য হারাবেন Omit

যেমন

interface A extends Record<string | number, number | string | boolean> {
    x: string;
    y: boolean;
}

export type B = Omit<A, 'x'> & { x: number };

let b: B = { x: 2, y: "hi" }; // no error on b.y! 

কারণটি হ'ল, Omitঅভ্যন্তরীণভাবে কেবল Exclude<keyof A, 'x'>কীগুলি চলে যা string | numberআমাদের ক্ষেত্রে সাধারণ হবে be সুতরাং, Bহয়ে যাবে {x: number; }এবং প্রকারের সাথে কোনও অতিরিক্ত সম্পত্তি গ্রহণ করবে number | string | boolean


এটি ঠিক করার জন্য, আমি OverridePropsনিম্নলিখিত হিসাবে একটি পৃথক ইউটিলিটি টাইপ নিয়ে এসেছি :

type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };

উদাহরণ:

type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };

interface A extends Record<string | number, number | string | boolean> {
    x: string;
    y: boolean;
}

export type B = OverrideProps<A, { x: number }>;

let b: B = { x: 2, y: "hi" }; // error: b.y should be boolean!

1

অন্য কারও যদি এটির জন্য জেনেরাল ইউটিলিটি ধরণের প্রয়োজন হয় তবে আমি নীচের সমাধানটি নিয়ে এসেছি:

/**
 * Returns object T, but with T[K] overridden to type U.
 * @example
 * type MyObject = { a: number, b: string }
 * OverrideProperty<MyObject, "a", string> // returns { a: string, b: string }
 */
export type OverrideProperty<T, K extends keyof T, U> = Omit<T, K> & { [P in keyof Pick<T, K>]: U };

আমার এটি দরকার ছিল কারণ আমার ক্ষেত্রে, ওভাররাইডের মূল চাবিকাঠিটি একটি জেনেরিক ছিল।

আপনার যদি Omitপ্রস্তুত না থাকে তবে প্রকার থেকে সম্পত্তি বাদ দিন


4
এটি ঠিক আমি যা খুঁজছিলাম, আমি আপনাকে যথেষ্ট ধন্যবাদ জানাতে পারি না: D: D: D
doodwardgb

@ উডওয়ার্ডজবি খুশি যে এটি অন্য কারও জন্য উপকারী ছিল :-)
টনি

0

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


আমার এই বিষয়টি সম্পর্কিত কিছু সমস্যা ছিল (ইন্টারফেসের বৈশিষ্ট্যগুলিকে ওভাররাইটিং), এবং এটিই আমি এটি পরিচালনা করছি:

  1. আপনি যে জাতীয় সম্ভাব্য প্রকারটি ব্যবহার করতে চান তা নিয়ে প্রথমে একটি জেনেরিক ইন্টারফেস তৈরি করুন।

আপনি defaultযেমন দেখতে পাচ্ছেন তেমন জেনেরিক প্যারামিটারের জন্য একটি মান চয়ন করতেও ব্যবহার করতে পারেন<T extends number | SOME_OBJECT = number>

type SOME_OBJECT = { foo: "bar" }

interface INTERFACE_A <T extends number | SOME_OBJECT = number> {
  property: T;
}
  1. তারপরে আপনি জেনেরিক প্যারামিটারে কোনও মান পাস করে (বা এটিকে বাদ দিয়ে ডিফল্ট ব্যবহার করুন): সেই চুক্তির ভিত্তিতে আপনি নতুন ধরণের তৈরি করতে পারেন:
type A_NUMBER = INTERFACE_A;                   // USES THE default = number TYPE. SAME AS INTERFACE_A<number>
type A_SOME_OBJECT = INTERFACE_A<SOME_OBJECT>  // MAKES { property: SOME_OBJECT }

এবং এই ফলাফল:

const aNumber: A_NUMBER = {
    property: 111  // THIS EXPECTS A NUMBER
}

const anObject: A_SOME_OBJECT = {
    property: {   // THIS EXPECTS SOME_OBJECT
        foo: "bar"
    }
}

টাইপস্ক্রিপ্ট খেলার মাঠ


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