Skip to content

Type alias = {} question #1945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jbondc opened this issue Feb 5, 2015 · 4 comments
Closed

Type alias = {} question #1945

jbondc opened this issue Feb 5, 2015 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@jbondc
Copy link
Contributor

jbondc commented Feb 5, 2015

type Json = {}

interface Data extends Json {
    foo: string
}

If a type is an alias for {}, should an interface be allowed to extend it?

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Feb 5, 2015
@RyanCavanaugh
Copy link
Member

No. Interfaces may only extend named object types. They can't extend primitives or anonymous object types.

In this case, type Json = {} should have been written as interface Json { } if the ability to extend from it was desired. It's rarely correct to use a type alias to define an alias for an object type.

See #957 (comment) (mostly that comment, but also ones above it) for an extended discussion of how type Json = {} was originally going to be disallowed for exactly this reason.

@danquirk
Copy link
Member

danquirk commented Feb 6, 2015

The latest copy of the language spec has some explanation of the difference between interfaces and type aliases:

3.9
Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases. For example, the interface type

interface Point {
    x: number;
    y: number;
}

could be written as the type alias

type Point = {
    x: number;
    y: number;
};

However, doing so means the following capabilities are lost:
• An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.
• An interface can have multiple merged declarations, but a type alias for an object type literal cannot.
• An interface can have type parameters, but a type alias for an object type literal cannot.

@danquirk
Copy link
Member

danquirk commented Feb 9, 2015

I believe the re-opening of type definitions was one of the primary reasons to not re-use interface as is. It seems a bit subtle to say interface Foo {} means a type that can be re-opened but interface Foo = {} means it cannot be reopened. Then you also need to know that interface= is necessary for aliasing union types but not other things. Obviously the distinction between interface {} and type= isn't necessarily significantly clearer from an intuitive perspective, but the use of different keywords does clearly suggest different semantics in a way that relatively minor syntax changes do not.

re: ItemApi2, it does look a little awkward but remember that the addItem syntax there is just sugar:

type ItemApi2 = {
    items: Item[];
    addItem: () => void;
}

and that doesn't look so strange.

One use case to remember is people often want to alias function types, but these are ultimately types with bodies. That is, this

type Callback = (data: string) => void;

seems nice to have (even more so if/when aliases allow generic parameters). People already used interfaces for this purpose (ex underscore/lodash.d.ts), but that necessarily allows your alias to be re-opened to include other members. In reality the type alias means:

type Callback = { (data: string): void; }

So if you don't allow types with bodies on the RHS then you can't alias function types.

We definitely went back and forth on the whole thing for awhile, considering whether/if to re-use interface in some fashion (with or without = or something) or if a new keyword was necessary for clarity.

@mhegazy
Copy link
Contributor

mhegazy commented Jun 12, 2015

looks like there is no actions/information required from this issue at this point. closing.

@mhegazy mhegazy closed this as completed Jun 12, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants