ใน typescript ความแตกต่างระหว่าง type และ interface คืออะไร?


114

อะไรคือความแตกต่างระหว่างสิ่งต่อไปนี้?

type Foo = { 
    foo: string 
};
interface Foo {
   foo: string;
}

3
ประเภทไม่สามารถขยายได้เช่นส่วนขยายอินเตอร์เฟซ ประเภทเป็นเพียงนามแฝงสำหรับประเภท
PSL

4
ดูคำแนะนำที่นี่: basarat.gitbooks.io/typescript/content/docs/types/…
basarat

2
ฉันใช้ประเภทสำหรับข้อมูลภายนอกเป็นส่วนใหญ่เช่นจากไฟล์ JSON หรือถ้าคุณเขียนเฉพาะฟังก์ชันโดยไม่ใช้คลาส OOP
Kokodoko

1
ฉันพบว่าบทความนี้มีประโยชน์ซึ่งอธิบายความแตกต่าง - medium.com/@martin_hotell/…
Sandeep GB

1
คำตอบที่ยอมรับนั้นล้าสมัย คำอธิบายที่อัปเดตโพสต์ที่นี่ (เนื่องจาก Google ดูเหมือนว่าจะเป็นที่ชื่นชอบ): stackoverflow.com/questions/37233735/…
jabacchetta

คำตอบ:


125

อินเทอร์เฟซสามารถขยายได้

interface A {
  x: number;
}
interface B extends A {
  y: string;
}

และยังเพิ่ม

interface C {
  m: boolean;
}
// ... later ...
interface C {
  n: number;
}

อย่างไรก็ตามประเภทนามแฝงสามารถแสดงถึงบางสิ่งที่อินเทอร์เฟซไม่สามารถทำได้

type NumOrStr = number | string;
type NeatAndCool = Neat & Cool;
type JustSomeOtherName = SomeType;

ดังนั้นโดยทั่วไปหากคุณมีประเภทวัตถุธรรมดาดังที่แสดงในคำถามของคุณอินเทอร์เฟซมักจะเป็นแนวทางที่ดีกว่า หากคุณพบว่าตัวเองต้องการเขียนสิ่งที่ไม่สามารถเขียนเป็นอินเทอร์เฟซได้หรือต้องการเพียงแค่ตั้งชื่ออื่นให้ใช้นามแฝงชนิดอื่น


3
Type aliases, however, can represent some things interfaces can'tดูเหมือนว่าสำหรับฉันตัวอย่างของคุณNeatAndCoolและJustSomeOtherNameสามารถสร้างเป็นอินเตอร์เฟซที่ขยายที่มีอยู่Neat, CoolหรือSomeTypeประเภท
Rudey

ตัวอย่างที่สองและสามสามารถสร้างได้ด้วยอินเทอร์เฟซ:interface NeatAndCool extends Neat, Cool {} interface JustSomeOtherName extends SomeType {}
peterjwest

3
การขยายสองอินเทอร์เฟซจะไม่ให้ผลลัพธ์เหมือนกับประเภทสี่แยกเสมอไปและไม่สามารถขยายทุกประเภทได้ (ในขณะที่ทุกประเภทสามารถใช้นามแฝงหรือใส่ลงในสหภาพ / ทางแยกได้)
Ryan Cavanaugh

1
ข้อดีของประเภทคืออะไร? เราพูดได้ไหมเมื่อเรามี interface ประเภทไม่มีประโยชน์?
Mostafa Saadatnia

4

นอกจากนี้อินเตอร์เฟซที่สามารถนำมาใช้


1
และวัตถุสามารถใช้งานได้หลายอินเทอร์เฟซclass Thing implements Neat, Cool
Kokodoko

1
คุณหมายความว่าอะไร ? ยังใช้ Type can b
nadav

3
นี่ควรเป็นความคิดเห็นไม่ใช่คำตอบ imo
Michael Kunst

เรียนเดฟคุณควรแสดงความคิดเห็นไม่ใช่คำตอบ จากคำตอบนี้คำตอบของคุณยังไม่ถูกต้อง
Mehrdad88sh

4

ประเภทเป็นเหมือนอินเทอร์เฟซและในทางกลับกัน: ทั้งสองอย่างสามารถใช้งานได้โดยคลาส แต่มีความแตกต่างที่สำคัญบางประการ: 1. เมื่อ Type ถูกนำไปใช้โดยคลาสคุณสมบัติที่เป็นของ Type จะต้องถูกเตรียมใช้งานภายในคลาสในขณะที่ Interface จะต้องถูกประกาศ 2. ตามที่ @ryan กล่าวถึง: อินเทอร์เฟซสามารถขยายส่วนต่อประสานอื่นได้ ประเภทไม่ได้

type Person = {
    name:string;
    age:number;
}

// must initialize all props - unlike interface
class Manager implements Person {
    name: string = 'John';
    age: number = 55;

    // can add props and methods
    size:string = 'm';
}

const jane : Person = {
    name :'Jane',
    age:46,

    // cannot add more proprs or methods
    //size:'s'
}

4

ความแตกต่างระหว่างสิ่งเหล่านี้มีอยู่แล้วในชุดข้อความนี้

type Foo = {
    foo: string
};
interface Foo {
    foo: string;
}

ที่นี่type Fooและinterface Fooมีลักษณะเกือบจะคล้ายกันจนสับสน

interfaceคือสัญญาว่าคุณสมบัติต่อไปนี้ (ที่นี่foo:string) ควรมีอยู่ในวัตถุ ไม่ใช่interface classใช้เมื่อภาษาไม่รองรับการสืบทอดหลายรายการ ดังนั้นinterfaceอาจเป็นโครงสร้างทั่วไประหว่างคลาสต่างๆ

class Bar implements Foo {
    foo: string;
}

let p: Foo = { foo: 'a string' };

แต่typeและinterfaceถูกนำมาใช้ในบริบทที่แตกต่างกันมาก

let foo: Foo;
let today: Date = new Date();

นี่typeของfooเป็นFooและเป็นtoday Dateมันเหมือนกับการประกาศตัวแปรซึ่งเก็บข้อมูลของตัวแปรชนิดอื่น typeเปรียบเสมือนส่วนเหนือของอินเทอร์เฟซคลาสลายเซ็นฟังก์ชันประเภทอื่น ๆ หรือแม้แต่ค่า (เช่นtype mood = 'Good' | 'Bad') ในตอนท้ายtypeอธิบายถึงโครงสร้างหรือค่าที่เป็นไปได้ของตัวแปร


4

เป็นเรื่องผิดที่จะพูดว่า "สามารถใช้งานอินเทอร์เฟซได้" เนื่องจากสามารถใช้งานประเภทได้เช่นกัน

type A = { a: string };


class Test implements A {

    a: string;
}

แม้ว่าคุณจะทำได้ แต่คุณไม่สามารถใช้ประเภทที่เป็น Union of types ได้ซึ่งสมเหตุสมผลโดยสิ้นเชิง :)


4

พิมพ์ typescript จะใช้ในการอ้างอิงอยู่แล้วประเภทที่มีอยู่ interfaceมันไม่สามารถที่จะขยายออกไปเช่น ตัวอย่างtypeได้แก่ :

type Money = number;
type FormElem = React.FormEvent<HTMLFormElement>;
type Person = [string, number, number];

คุณสามารถใช้ Rest and Spread ในประเภท:

type Scores = [string, ...number[]];
let ganeshScore = ["Ganesh", 10, 20, 30]
let binodScore = ["Binod", 10, 20, 30, 40]

ในทางกลับกันอินเทอร์เฟซช่วยให้คุณสามารถสร้างประเภทใหม่ได้

interface Person{
  name: string,
  age: number, 
}

Interface can be extended with extends keyword.
interface Todo{
  text: string;
  complete: boolean;
}

type Tags = [string, string, string]

interface TaggedTodo extends Todo{
 tags: Tags
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.