Uh oh!
There was an error while loading. Please reload this page.
Type aliases and other changes in language specification - #998
Conversation
Adam Freidin (sparecycles)
commented
Oct 30, 2014
Could you clarify why a type is allowed to reference a union of a primitive and an anonymous type but not an anonymous type by itself? typeText=string|{text: string};// <-- example in spectypePoint={x: number;y: number;};// <-- explicitly disallowed by spec |
Anders Hejlsberg (ahejlsberg)
commented
Oct 30, 2014
A type alias for an anonymous object type literal: typePoint={x: number;y: number;};would be almost the same as an interface declaration: interfacePoint{x: number;y: number;}The subtle differences include:
We feel that the confusion caused by these differences are better avoided. |
Anders Hejlsberg (ahejlsberg)
commented
Oct 30, 2014
I should add that an alternative to the error would be to just treat type alias declarations for object type literals as equivalent to interface declarations. We discussed doing that, but we thought it would be odd for such type alias declarations to merge with other type alias or interface declarations for the same name. But disallowing merging would then again make them different from interfaces. Anyway, I could be persuaded we should just say type aliases for object type literals are exactly equivalent to interface declarations, merging and all. |
Adam Freidin (sparecycles)
commented
Oct 30, 2014
I understand that there are subtle semantic differences (which could be employed to create an interface type which can't be extended) but I feel we don't need to have an arbitrary restriction in order to sidestep some perceived difficulty down the line. All I can do is urge you to reconsider. If you don't reconsider, I can always work around the restriction by defining typePoint={x: number;y: number;}|{x: number;y: number;};😉 |
Ryan Cavanaugh (RyanCavanaugh)
commented
Oct 30, 2014
We didn't really like the carve-out for object types either, but it seems better than the alternatives. Are there specific use cases where you want to write |
Adam Freidin (sparecycles)
commented
Oct 30, 2014
Mainly philosophical, given that it's supported as part of a union. I don't think type aliases should be extendable. In that sense Another thing to consider is function types: typefun=()=>number;// allowedtypefun={// not allowed?(): number;(_:string): string;};By disallowing the second one, the ability to declare overloaded function type aliases is restricted to exported interfaces only. |
Ryan Cavanaugh (RyanCavanaugh)
commented
Oct 30, 2014
The danger is that if we don't make That's the same reason we allowed shorthand function types as alias targets -- |
Adam Freidin (sparecycles)
commented
Oct 30, 2014
I understand your reasons. I still disagree. I have to argue that .d.ts authors would be, in general, more technical than .d.ts users, and could be trusted to use type v.s. interface effectively. But I don't think I can contribute any more to this discussion. Thanks for your time. |
Anders Hejlsberg (ahejlsberg)
commented
Oct 30, 2014
Adam Freidin (@sparecycles)Ryan Cavanaugh (@RyanCavanaugh) I do agree it is an odd restriction and one that we're not particularly fond of. I'm starting to think we should just allow it and note the differences (and their consequences) in the Language Specification. |
Noel Abrahams (NoelAbrahams)
commented
Oct 31, 2014
The original objection to this was that if we wanted to annotate the parameter in the following function: functionfoo(point: {x: number;y: number}){}with the introduction of type aliases, there would be three ways of annotating // A. Using an interfaceinterfacePoint{x: number;y: number;}// B. Using typeof with type aliasesvarpoint: {x: number;y: number};typePoint=typeofpoint;// C. Directly declaring with type aliasestypePoint={x: number;y: number};All three methods of declaring My specific objection is that in an organisation, when there is more than one way to accomplish the same thing, we end up having half the people using one mechanism and the other half the other. Then we have situations of people correcting each other's coding styles in an endless death spiral 😃 . This is of course why linters exist, but I was arguing for the problem to be resolved at source. However, in this case, since only the third mechanism is prohibited, it doesn't really achieve the desired result in any case. My preference is for type aliases to be restricted to union and tuple types: typeu=string|number|{n: string};typet=[number,number];types=string;// errorWe have lived without type aliases for two years now without a significant demand from the community. |
Adam Freidin (sparecycles)
commented
Oct 31, 2014
I think we have to ask ourselves, are we adding type aliases to fill a particular need with union and tuple types, or are we extending typescript with a new feature? |
Anders Hejlsberg (ahejlsberg)
commented
Nov 1, 2014
I think we just have to accept the overlap between interface declarations and type alias declarations. The key observation here is that an alias is _exactly_ the same thing as writing the type it aliases, and since anonymous object type literals overlap with interface declarations, then so do aliases to object type literals. At the end of the day, a lot of this comes down to the fact that we have a structural type system and that there will always be multiple ways to write a particular type. I completely agree that it would ideal not to have this overlap. However, artificial restrictions seem like a cure that's worse than the disease, so I think we should drop them for now. |
Anders Hejlsberg (ahejlsberg)
commented
Nov 1, 2014
Updated Type Alias section in the spec to describe differences between interfaces and type aliases for object type literals. |
Cyrus Najmabadi (CyrusNajmabadi)
commented
Nov 1, 2014
Anders Hejlsberg (@ahejlsberg) The updated section looks great! |
Type aliases and other changes in language specification
How about type alias with type parameters? |
Ryan Cavanaugh (RyanCavanaugh)
commented
Jan 7, 2015
Daniel Earwicker (@danielearwicker) Can you log a separate suggestion issue for that? Thanks! |
Logged #1616 Type aliases requiring type parameters |
Changes in this PR: