É possível estender tipos no TypeScript?

156

Digamos que eu tenha o seguinte tipo:

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

Agora eu quero estender esse tipo, ou seja,

type UserEvent extends Event = {
   UserId: string; 
}

Isso não funciona. Como posso fazer isso?

Kousha
fonte
3
A typepalavra-chave é usada para definir aliases de tipo , não interfaces ou classes.
Heretic Monkey

Respostas:

285

A palavra-chave extendspode ser usada apenas para interfaces e classes.

Se você apenas deseja declarar um tipo que possui propriedades adicionais, pode usar o tipo de interseção :

type UserEvent = Event & {UserId: string}

ATUALIZAÇÃO para TypeScript 2.2, agora é possível ter uma interface que estenda o tipo de objeto , se o tipo atender a algumas restrições:

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

interface UserEvent extends Event {
   UserId: string; 
}

Não funciona ao contrário - UserEventdeve ser declarado como interface, e não typese você quiser usar a extendssintaxe.

E ainda é impossível usar extend com tipos arbitrários - por exemplo, ele não funciona se Eventfor um parâmetro de tipo sem restrições.

artem
fonte
Estou usando o TS v3.5.2 e não consigo que uma interface estenda um tipo. interface A<T> extends B<T> {blar}Uma interface só pode estender um tipo de objecto ou intersecção de tipos de objectos com os membros conhecidos estaticamente
WORMSS
O @WORMSS fazendo isso interface Identifiable<T> extends T { id: string }me dá o erro "Uma interface só pode estender um tipo de objeto ou interseção de tipos de objeto com membros estaticamente conhecidos. T (2312)"
maninak 15/06
22

você pode cruzar tipos:

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

em algum lugar no seu código, agora você pode fazer:

const some: TypeC = {
    nameB: 'B',
    nameA: 'A',
};
Stanislav
fonte
6

O que você está tentando alcançar é equivalente a

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

interface UserEvent extends Event {
   UserId: string; 
}

A maneira como você definiu os tipos não permite especificar herança, no entanto, é possível obter algo semelhante usando tipos de interseção, como artem apontou.

olydis
fonte
8
Sim, mas eu não gosto da palavra interfacequando eu realmente quero dizer atype
Kousha
É justo o suficiente, então a resposta do artem deve servir para você :) #
2819 olydis
-1

Pode estar abaixo da abordagem será útil para alguém TS com reactjs

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

interface UserEvent<T> extends Event<T> {
    UserId: string;
}
Jaison
fonte