Можно ли расширить типы в Typescript?

156

Скажем, у меня такой тип:

type Event = {
   name: string;
   dateCreated: string;
   type: string;
}

Теперь я хочу расширить этот тип, т.е.

type UserEvent extends Event = {
   UserId: string; 
}

Это не работает Как я могу это сделать?

Kousha
источник
3
typeКлючевое слово используется для определения псевдонимов типов , а не интерфейсов или классов.
Еретик Обезьяна

Ответы:

285

Ключевое слово extendsможет использоваться только для интерфейсов и классов.

Если вы просто хотите объявить тип, который имеет дополнительные свойства, вы можете использовать тип пересечения :

type UserEvent = Event & {UserId: string}

ОБНОВЛЕНИЕ для TypeScript 2.2, теперь возможно иметь интерфейс, расширяющий объектоподобный тип , если тип удовлетворяет некоторым ограничениям:

type Event = {
   name: string;
   dateCreated: string;
   type: string;
}

interface UserEvent extends Event {
   UserId: string; 
}

Он не работает наоборот - UserEventдолжен быть объявлен как интерфейс, а не, typeесли вы хотите использовать extendsсинтаксис.

И все еще невозможно использовать extend с произвольными типами - например, он не работает, если Eventявляется параметром типа без каких-либо ограничений.

артем
источник
Я использую TS v3.5.2, и у меня нет интерфейса, расширяющего тип. interface A<T> extends B<T> {blar}Интерфейс может только расширять тип объекта или пересечение типов объектов со статически известными членами
WORMSS
@WORMSS при этом interface Identifiable<T> extends T { id: string }выдает ошибку «Интерфейс может расширять только тип объекта или пересечение типов объектов со статически известными members.ts (2312)»
манинак
22

вы можете пересекать типы:

type TypeA = {
    nameA: string;
};
type TypeB = {
    nameB: string;
};
export type TypeC = TypeA & TypeB;

где-то в вашем коде теперь вы можете сделать:

const some: TypeC = {
    nameB: 'B',
    nameA: 'A',
};
Станислав
источник
6

То, чего вы пытаетесь достичь, эквивалентно

interface Event {
   name: string;
   dateCreated: string;
   type: string;
}

interface UserEvent extends Event {
   UserId: string; 
}

То, как вы определили типы, не позволяет указать наследование, однако вы можете добиться чего-то подобного, используя типы пересечения, как указал артем .

olydis
источник
8
Да, но мне не нравится это слово, interfaceкогда я на самом деле имею в видуtype
Коуша
Справедливо, тогда ответ
артема
-1

Может быть, ниже подход будет полезен для кого-то TS с реагировать

interface Event {
   name: string;
   dateCreated: string;
   type: string;
}

interface UserEvent<T> extends Event<T> {
    UserId: string;
}
Jaison
источник