टाइपस्क्रिप्ट: इंटरफेस बनाम प्रकार


713

इन कथनों (इंटरफ़ेस बनाम प्रकार) में क्या अंतर है?

interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};

4
इस लेख में अंतर की व्याख्या करते हुए पाया गया - मध्यम.
संदीप जीबी

जवाबों:


572

के अनुसार टाइपप्रति भाषा विशिष्टता :

एक इंटरफ़ेस घोषणा के विपरीत, जो हमेशा एक नामित वस्तु प्रकार का परिचय देता है, एक प्रकार का उपनाम अन्य प्रकार के किसी भी प्रकार के लिए एक नाम पेश कर सकता है, जिसमें आदिम, संघ और चौराहे प्रकार शामिल हैं।

विनिर्देशन का उल्लेख है:

इंटरफ़ेस प्रकार में ऑब्जेक्ट प्रकार शाब्दिक के लिए उपनाम टाइप करने के लिए कई समानताएं हैं, लेकिन चूंकि इंटरफ़ेस प्रकार अधिक क्षमताओं की पेशकश करते हैं, इसलिए वे आमतौर पर उपनाम टाइप करना पसंद करते हैं। उदाहरण के लिए, इंटरफ़ेस प्रकार

interface Point {
    x: number;
    y: number;
}

प्रकार उपनाम के रूप में लिखा जा सकता है

type Point = {
    x: number;
    y: number;
};

हालाँकि, ऐसा करने का अर्थ है कि निम्नलिखित क्षमताएं खो गई हैं:

  • एक इंटरफ़ेस का नाम एक्सटेंड्स या इम्प्लीमेंटेशन क्लॉज़ में रखा जा सकता है, लेकिन ऑब्जेक्ट प्रकार शाब्दिक के लिए एक अन्य उपनाम TS 2.7 के बाद से सत्य नहीं रह सकता है।
  • एक इंटरफ़ेस में कई मर्ज किए गए घोषणाएँ हो सकती हैं , लेकिन ऑब्जेक्ट प्रकार शाब्दिक के लिए एक प्रकार का उपनाम अन्य नहीं हो सकता।

109
दूसरे अंतर में "कई मर्ज किए गए घोषणाओं" का क्या अर्थ है?
जहाराली

66
@ जहाराली यदि आप दो बार इंटरफ़ेस परिभाषित करते हैं, तो टाइपस्क्रिप्ट उन्हें एक में मिला देता है।
एंड्री फेडोरोव

39
@ जर्राहाली यदि आप दो बार टाइप करते हैं, तो टाइपस्क्रिप्ट आपको त्रुटि देता है
एंड्री फेडोरोव

18
@jrahhali interface Point { x: number; } interface Point { y: number; }
ग्रीको

20
मेरा मानना ​​है कि पहला बिंदु extends or implementsअब ऐसा नहीं है। प्रकार को बढ़ाया और कार्यान्वित किया जा सकता है class। यहाँ एक उदाहरण है typescriptlang.org/play/...
dark_ruby

771

2019 अपडेट


वर्तमान उत्तर और आधिकारिक दस्तावेज पुराने हैं। और टाइपस्क्रिप्ट के लिए नए लोगों के लिए, शब्दावली का इस्तेमाल बिना उदाहरण के स्पष्ट नहीं है। नीचे अप-टू-डेट अंतर की एक सूची है।

1. वस्तुएं / कार्य

दोनों का उपयोग किसी वस्तु के आकार या फ़ंक्शन हस्ताक्षर का वर्णन करने के लिए किया जा सकता है। लेकिन वाक्यविन्यास अलग है।

इंटरफेस

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

उपनाम लिखें

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

2. अन्य प्रकार

इंटरफ़ेस के विपरीत, अन्य प्रकार जैसे कि आदिम, यूनियनों और ट्यूपल्स के लिए भी उपनाम का उपयोग किया जा सकता है।

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

3. विस्तार

दोनों को बढ़ाया जा सकता है, लेकिन फिर से, वाक्यविन्यास भिन्न होता है। इसके अतिरिक्त, ध्यान दें कि एक अंतरफलक और प्रकार उर्फ ​​परस्पर अनन्य नहीं हैं। एक इंटरफ़ेस एक प्रकार का उपनाम, और इसके विपरीत का विस्तार कर सकता है।

इंटरफ़ेस इंटरफ़ेस का विस्तार करता है

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

प्रकार उपनाम अन्य प्रकार का उपनाम है

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

इंटरफ़ेस प्रकार उर्फ ​​का विस्तार करता है

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

प्रकार उर्फ ​​इंटरफ़ेस का विस्तार करता है

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

4. औजार

एक वर्ग एक इंटरफ़ेस या टाइप उर्फ ​​को लागू कर सकता है, दोनों एक ही सटीक तरीके से। ध्यान दें कि एक वर्ग और इंटरफ़ेस को स्थिर ब्लूप्रिंट माना जाता है। इसलिए, वे एक प्रकार के उपनाम को लागू / विस्तारित नहीं कर सकते हैं जो एक संघ प्रकार का नाम देता है।

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

5. घोषणा विलय

एक प्रकार के उपनाम के विपरीत, एक इंटरफ़ेस को कई बार परिभाषित किया जा सकता है, और एक एकल इंटरफ़ेस के रूप में माना जाएगा (सभी घोषणाओं के सदस्यों के विलय के साथ)।

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };

9
यदि आधिकारिक दस्तावेज पुराना है, तो आपके द्वारा प्रदान की गई जानकारी की पुष्टि कहां की जा सकती है?
IX3

59
इस पोस्ट के आधार पर, ऐसा लगता है कि एक प्रकार के उपनाम पर इंटरफ़ेस चुनने का एकमात्र कारण यह है कि यदि आप इंटरफेस के घोषणा विलय (बिंदु 5) सुविधा का उपयोग करना चाहते हैं। इसके अलावा, वे समतुल्य हैं (और मैं तर्क देता हूं कि टाइप अलायस अधिक संक्षिप्त वाक्य रचना प्रदान करते हैं)।
अधिकतम फेरी

17
मैं हमेशा ऑब्जेक्ट प्रकार शाब्दिक के लिए इंटरफेस का उपयोग कर रहा हूं, अन्यथा प्रकार का उपयोग करना अधिक समझ में आता है, मुझे यह भी लगता है कि घोषणा विलय का उपयोग किसी भी तरह से नहीं किया जाना चाहिए, वास्तव में मैं कभी भी यह उम्मीद नहीं करूंगा कि प्रोजेक्ट के किसी अन्य फ़ाइल में एक इंटरफ़ेस घोषित किया जा रहा है अतिरिक्त गुण, प्रकार की जाँच मूल रूप से आपके जीवन को आसान बनाने के लिए की जाती है ताकि इस निंजा जैसे इंटरफेस के साथ इसे कठिन न बनाया जा सके: D
Ahmed Kamal

8
तो मूल रूप से, यह "लगभग एक व्यक्तिगत" पसंद है जिसे हम वास्तव में उपयोग करके सहज महसूस करते हैं? एक कारण के अलावा, आप बस का उपयोग कर सकते हैं typeया interface? मुझे अभी भी भ्रम है कि मुझे एक या दूसरे का उपयोग कब करना चाहिए।
जोसेफ ब्रिग्स

7
क्या कोई व्यक्ति इस बात के लिए कुछ प्रेरणा दे सकता है कि आप इंटरफ़ेस विलय क्यों चाहते हैं? यह मेरे लिए संभावित रूप से भ्रमित करने वाला लगता है। आप अपने इंटरफ़ेस की परिभाषा को विभिन्न ब्लॉकों में क्यों फैलाना चाहेंगे?
वंचिती46

95

टाइपस्क्रिप्ट 3.2 (नवंबर 2018) के अनुसार, निम्नलिखित सत्य है:

यहां छवि विवरण दर्ज करें


9
क्या आप इस बारे में अधिक जानकारी प्रदान कर सकते हैं कि आपके द्वारा प्रदान की गई तालिका / छवि कैसे उत्पन्न हुई? जैसे स्रोत कोड या प्रलेखन के लिंक
iX3

23
हां, मेरा मतलब था कि सामग्री का स्रोत, इसकी प्रस्तुति नहीं है।
IX3

3
मेरा मानना ​​है कि एक वर्ग या तो एक प्रकार या इंटरफ़ेस का विस्तार कर सकता है, और मैं वास्तव में नहीं देख सकता कि आप क्यों चाहते हैं ??
दान राजा

7
पाठ की छवियों को पोस्ट करने से बचें, इसके बजाय वास्तविक पोस्ट को सीधे अपनी पोस्ट में शामिल करें। पाठ की छवियां आसानी से पार्स करने योग्य या खोज योग्य नहीं हैं, और नेत्रहीन उपयोगकर्ताओं के लिए सुलभ नहीं हैं।
एंड्रयू मार्शल

2
इस तालिका में इसकी सामग्री का समर्थन करने के लिए किसी भी स्रोत का अभाव है और मैं इस पर भरोसा नहीं करूंगा। उदाहरण के लिए, आप typeकुछ सीमाओं के साथ (और टाइपस्क्रिप्ट 3.7 के रूप में इन सीमाओं को समाप्त कर दिया गया है) का उपयोग करके पुनरावर्ती प्रकारों को परिभाषित कर सकते हैं । इंटरफेस प्रकारों का विस्तार कर सकते हैं। कक्षाएं प्रकार लागू कर सकती हैं। इसके अलावा, डेटा को टेबल के स्क्रीनशॉट के रूप में पेश करना बिगड़ा हुआ लोगों के लिए पूरी तरह से दुर्गम बनाता है।
मिचेल मिस्ज़ेसिस्ज़िन

22

https://www.typescriptlang.org/docs/handbook/advanced-types.html

एक अंतर यह है कि इंटरफेस एक नया नाम बनाते हैं जो हर जगह उपयोग किया जाता है। प्रकार उपनाम एक नया नाम नहीं बनाते हैं - उदाहरण के लिए, त्रुटि संदेश उपनाम नाम का उपयोग नहीं करेंगे।


30
यह अब पुराना है और टाइपस्क्रिप्ट 2.1 के बाद से सच नहीं है। देख। medium.com/@martin_hotell/…
डेमएक्स

5

प्रकार के उदाहरण:

// एक वस्तु के लिए एक पेड़ संरचना बनाएँ। चौराहे (और) की कमी के कारण आप इंटरफ़ेस के साथ ऐसा नहीं कर सकते

type Tree<T> = T & { parent: Tree<T> };

// केवल कुछ मान निर्दिष्ट करने के लिए एक चर को प्रतिबंधित करने के लिए टाइप करें। संघों का संघ नहीं है (!)

type Choise = "A" | "B" | "C";

// प्रकारों के लिए धन्यवाद, आप एक सशर्त तंत्र के लिए गैर-योग्य प्रकार के धन्यवाद की घोषणा कर सकते हैं।

type NonNullable<T> = T extends null | undefined ? never : T;

इंटरफ़ेस के उदाहरण:

// आप OOP के लिए इंटरफ़ेस का उपयोग कर सकते हैं और ऑब्जेक्ट / क्लास कंकाल को परिभाषित करने के लिए 'इम्प्लीमेंट्स' का उपयोग कर सकते हैं

interface IUser {
    user: string;
    password: string;
    login: (user: string, password: string) => boolean;
}

class User implements IUser {
    user = "user1"
    password = "password1"

    login(user: string, password: string) {
        return (user == user && password == password)
    }
}

// आप अन्य इंटरफेस के साथ इंटरफेस का विस्तार कर सकते हैं

    interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }

1

पहले से ही प्रदान किए गए शानदार उत्तरों के अलावा, जब यह बनाम बनाम इंटरफेस तक पहुंच जाता है, तो ध्यान देने योग्य अंतर होते हैं। मैं हाल ही में कुछ मामलों में भाग लेता हूं जहां एक इंटरफ़ेस काम नहीं कर सकता है:

  1. इंटरफ़ेस का उपयोग करके यूनियन प्रकार का विस्तार नहीं किया जा सकता है
  2. सामान्य इंटरफ़ेस का विस्तार नहीं किया जा सकता

-2

प्रलेखन समझाया है

  • एक अंतर यह है कि इंटरफेस एक नया नाम बनाते हैं जो हर जगह उपयोग किया जाता है। प्रकार उपनाम कोई नया नाम नहीं बनाते हैं - उदाहरण के लिए, त्रुटि संदेश उपनाम नाम का उपयोग नहीं करेंगे। टाइपस्क्रिप्ट के पुराने संस्करण, प्रकार उपनामों को विस्तारित नहीं किया जा सकता है या उन्हें लागू नहीं किया जा सकता है (न ही वे अन्य प्रकारों का विस्तार / कार्यान्वयन कर सकते हैं)। संस्करण 2.7 के रूप में, नए चौराहे प्रकार बनाकर प्रकार के उपनामों को बढ़ाया जा सकता है
  • दूसरी ओर, यदि आप एक इंटरफ़ेस के साथ कुछ आकृति व्यक्त नहीं कर सकते हैं और आपको एक संघ या टपल प्रकार का उपयोग करने की आवश्यकता है, तो टाइप एलियाज़ आमतौर पर जाने का तरीका है।

इंटरफेस बनाम प्रकार उपनाम

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.