admin管理员组

文章数量:1126345

Say I have the following type:

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

I now want to extend this type, i.e.

type UserEvent extends Event = {
   UserId: string; 
}

This doesn't work. How can I do this?

Say I have the following type:

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

I now want to extend this type, i.e.

type UserEvent extends Event = {
   UserId: string; 
}

This doesn't work. How can I do this?

Share Improve this question asked Dec 29, 2016 at 18:10 KoushaKousha 36.1k58 gold badges185 silver badges313 bronze badges 2
  • 12 The type keyword is used to define type aliases, not interfaces or classes. – Heretic Monkey Commented Dec 29, 2016 at 18:20
  • Your code is like saying that the true name is an alias, and it doesn't make sense. – NeoZoom.lua Commented Apr 7, 2024 at 23:04
Add a comment  | 

7 Answers 7

Reset to default 1416

The keyword extends can be used for interfaces and classes only.

If you just want to declare a type that has additional properties, you can use intersection type:

type UserEvent = Event & {UserId: string}

UPDATE for TypeScript 2.2, it's now possible to have an interface that extends object-like type, if the type satisfies some restrictions:

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

interface UserEvent extends Event {
   UserId: string; 
}

It does not work the other way round - UserEvent must be declared as interface, not a type if you want to use extends syntax.

And it's still impossible to use extend with arbitrary types - for example, it does not work if Event is a type parameter without any constraints.

you can intersect types:

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

somewhere in you code you can now do:

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

A generic extension type can be written as follows:

type Extension<T> = T & { someExtensionProperty: string }

What you are trying to achieve is equivalent to

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

interface UserEvent extends Event {
   UserId: string; 
}

The way you defined the types does not allow for specifying inheritance, however you can achieve something similar using intersection types, as artem pointed out.

You can also do that by using type in addition to interface:

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

type UserEvent = {
   UserId: string; 
} & Event

You cannot constrain an alias.

This is OK, even though the semantic is incorrect:

type UserEvent /* extends Event */ = {
   UserId: string; 
}

but this is not:

type UserEvent extends Event = {
   UserId: string; 
}

To correctly express what you mean, you can use & Event instead of extends Event:

type UserEvent = { UserId: string } & Event;

If you have a type defined with Union (more than one possible types) and you want to add an additional type, you can do something like this

interface TextInputProps = { type: string };
interface TextAreaProps  = { type: string | number };

export type InputCompProps = TextInputProps | TextAreaProps

to

interface CustomProps = { length: number };
export type InputCompProps = (TextInputProps | TextAreaProps) & CustomProps

本文标签: javascriptPossible to extend types in TypescriptStack Overflow