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.
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',
};
Videos
I've randomly run into this looking at random TS snippets online or library source codes. Here's an example of it inside ts-toolbelt.
I thought the following two examples were equivalent; are they not?
type WithAny<T extends any> = T; type WithoutAny<T> = T;
Extends lets you place restrictions on which types can be used with your type parameter. I find it can help to read extends as "is assignable to".
This means that only types which are assignable to any can be used with WithAny.
Since everything is assignable to any it doesn't place any additional restrictions on T in your example so they would be equivalent.
I'm not sure why ts-toolbelt does this, its description hints that it might be a bit of a hack to improve the display of a type error.
I think there no difference here. There's one scenario (afaik) where you'd actually need to extend any explicitly: generic in arrow functions
const foo = <T extends any>() => { /* whatever */ }
Otherwise there'll be parsing ambiguity for TSC.