2017-01-16 2 views
4

Я не могу понять, когда вы когда-либо захотите использовать type вместо interface для переменной в машинописном машиностроении. Предположим, что следующие два:Когда использовать типы (vs interface) в TS

type User = { 
    id: string; 
    name: string; 
    type: string; 
} 

interface User { 
    id: string; 
    name: string; 
    type: string; 
} 

можно определить переменную как с точно такой же был const user: User = .... Однако, вот все, что я могу сделать с interface, что я не могу сделать с types:

// Extension: 
interface AdminUser extends User { 
    permissions: string[]; 
    role: string; 
} 

// Using in abstract method: 
abstract class Home { 
    abstract login(user: User): void; 
} 

class AdminHome extends Home { 
    login(user: AdminUser) { 
     ... 
    } 
} 

Просто назвать несколько.

Так что мой вопрос: когда бы вы хотели использовать type?

ответ

11

Если я не ошибаюсь, вы не совсем поняли, какой целью является интерфейс по сравнению с типом.

В терминах ООП интерфейсы не имеют реализаций. Типы делают. Таким образом, интерфейс в основном бесполезен, если только этот тип не реализует его. Кроме того, тип может распространять только один тип. Но он может реализовывать множество интерфейсов.

Но что это значит ...

Скажем, у вас есть автомобиль, и пользователя. Очень разные типы, которые вы не сразу думаете, как одно и то же в любом практическом смысле. Некоторые могут сказать: «ну, вы должны создать ICar и IUser». Но на самом деле, это просто не практический способ думать об интерфейсах. Было бы странным, если бы Пользователь реализовал ICar, и/или, похоже, ICar делает то же самое, что и Car. Какая разница с другим программистом, смотрящим на код?

Скажите, что вы хотите, чтобы они оба были (снова просто для этого), «Self Describable», и вы хотите, чтобы они оба предоставили информацию таким же образом. Таким образом, вы бы создать:

ISelfDescribable { 
    getSelfDescription (); 
} 

Теперь, вы могли бы сделать это:

Car implements ISelfDescribable { 
    getSelfDescription (return "I am a car!"); 
} 

User implements ISelfDescribable { 
    getSelfDescription (return ...some other completely different way of getting the info...); 
} 

Массив этих объектов будет (думать о том, как еще вы могли бы сделать это без интерфейсов):

Array<ISelfDescribable> 

Теперь вы (и любой другой разработчик, смотрящий на код) знают, что любой объект в этом массиве, независимо от конкретного типа, реализует «поведение» ISelfDesribable. Если вы думаете об этом, нет необходимости НИКОГДА знать, что такое тип, если вы его не реализуете, вы просто заботитесь о поведении. Но вам все равно нужен тип для реализации этого поведения.

Скажите, что однажды вы хотели, чтобы оба этих объекта были «Надежными». Они оба должны иметь метод, "setInsurancePolicy". Вы можете создать IInsurable { setInsurancePolicy (policy : Policy) } и реализовать его в типах. Теперь у вас есть объекты, которые являются как ISelfDescribable, так и IInsurable, и вы можете ввести массив этих объектов как один.

Для меня большая лампочка погасла, когда я обнял ее: типы (и иерархии типов) должны быть связаны с конкретными вещами. Интерфейсы должны быть связаны с поведением, которое может использоваться для разных типов. Это еще не все, но, по крайней мере, дает представление о том, почему вы выбираете интерфейс или тип. Они представляют разные вещи с точки зрения программирования, даже если они выглядят одинаково.

(Приложение: такие языки, как Scala, не воспринимают в терминах интерфейсов таким образом. У них есть понятие «поведения», но вы также можете реализовать поведение и переопределить их. Это может быть слишком много академического взрыва для этот конкретный вопрос, но эй, мне нужно убить всех монстров в подземелье, а не только тех, для квеста).

Смежные вопросы