Skip to content
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

Add empty tuple type #14646

Closed
wants to merge 4 commits into from
Closed

Add empty tuple type #14646

wants to merge 4 commits into from

Conversation

lefb766
Copy link

@lefb766 lefb766 commented Mar 14, 2017

Fixes #13126

Open question: should a non-empty tuple be assignable to []?

People may think it should be, given that you can assign [number, string] to [number].
However, the index signature of [] which is never blocks such assignment.

I think this isn't going to be a problem at least for now before variadic tuples (#5453) lands.
If you need common type of all tuples, you can simply use {}[] or any[].

Is there any other problemic scenario?

Related discussion: #6229

return !!getPropertyOfType(type, "0") || isEmptyTupleType(type);
}

function isEmptyTupleType(type: Type): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be to use === directly, so I think you should drop isEmptyTupleType and just add || type === emptyTupleType on line 8914

@@ -17115,10 +17118,7 @@ namespace ts {

function checkTupleType(node: TupleTypeNode) {
// Grammar checking
const hasErrorFromDisallowedTrailingComma = checkGrammarForDisallowedTrailingComma(node.elementTypes);
if (!hasErrorFromDisallowedTrailingComma && node.elementTypes.length === 0) {
grammarErrorOnNode(node, Diagnostics.A_tuple_type_element_list_cannot_be_empty);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can delete this error from diagnosticsMessages.json since this is the only usage.

var et0 = et[0]; // never
var et0: never;

et = []; // Ok
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add this same check in a new file, something like tupleTypesStrictNullCheck.ts, with the first line // @strictNullChecks: true to turn on strict null checks?

@lefb766
Copy link
Author

lefb766 commented Mar 20, 2017

@sandersn Your comments are already reflected

if (elementTypes.length) {
return createTupleType(elementTypes);
}
return createTupleType(elementTypes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should update the createTupleType function to return the emptyTupleType singleton if elementTypes is empty.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We need to make the condition persistent over future updates. A fix is pushed!

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. @RyanCavanaugh or @ahejlsberg can you take a look too?

@@ -6209,7 +6210,13 @@ namespace ts {
return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity));
}

function createTupleType(elementTypes: Type[]) {
function createTupleType(elementTypes: Type[]): TypeReference {
// We have to ensure that we get same instance for empty tuple type,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTupleTypeOfArity caches the resulting tuple type, so not sure why we need special handling here.

Copy link
Contributor

@mhegazy mhegazy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usage of getTupleTypeOfArity should be sufficient

@KiaraGrouwstra
Copy link
Contributor

I've made an attempt to revive this PR taking into account the requested changes at #17762.

@lefb766
Copy link
Author

lefb766 commented Aug 24, 2017

@tycho01 oh, great! but my bad! I left this PR untouched for so long time and was even unnoticed the update on the original issue until today.

I appreciate you reused my code! Thanks!

Just wondering. Are you going to update them further and implement the additional restrictions you mentioned in #13126 (comment) ?
Currently, I'm getting difficulties finding functional update in your PR... looks they are just pure code cleaning and conflict resolution.

@KiaraGrouwstra
Copy link
Contributor

KiaraGrouwstra commented Aug 24, 2017

@lefb766: right, I hadn't included those in there.

To answer by sub-topic there:

  • known length, fixing Proposal: strict and open-length tuple types #6229: I filed a separate PR for this at Make tuples have known length #17765. The reason I separated them was that adding empty tuples should be uncontroversial (explicitly marked as 'Accepting PRs' at Empty tuple type now meaningful (at least, in unions) #13126), so I didn't wanna lump them with another feature the TS team had so far been silent on.
  • ditch mutating methods: this was part of my original plan for that Make tuples have known length #17765, making a new Tuple interface extending ReadonlyArray with a length property. This caused the project to not compile anymore though, at which point I'd just quickly settled on letting it extend Array instead, as the length was my primary concern. I then got issues about it not seeing my new interface on half of the tests (wth), at which point I opted to just set that length directly from createTupleTypeForArity instead, foregoing the new interface as length had become its sole added feature.
  • no index signature: I wasn't initially convinced of this, largely in fear of breaking more still than at my ReadonlyArray attempt, though I've recently been swayed this change seems a good thing. I guess it means copying ReadonlyArray into a new Tuple interface, similar minus the index. I wish I understood why we have several copies of this interface in lib.d.ts instead of just having them extend one -- if extending is okay, I'd imagine ReadonlyArray could just be extending this Tuple interface to just add its index too.

@lefb766
Copy link
Author

lefb766 commented Aug 25, 2017

@tycho01 Thanks for explaining. I see, you have another PR.

It turns out it will be harder to find difference between #17762 and this one if I happen to solve the conflict.
I don't have idea on how to deal with this type of situation. You have?

Your investigation on the sup-topic looks interesting though. Nice work.
I have a few opinion on the topics but it may be irrelevant to write them here.

@KiaraGrouwstra
Copy link
Contributor

@lefb766: wanna just stick with your PR then? If you follow mhegazy's change you may be done. :)

I'd be interested in your take on the topic, but I think the others in #13126 would be too!

@lefb766
Copy link
Author

lefb766 commented Aug 26, 2017

@tycho01 Fair point. I'll continue this work. Sorry for bothering you and others.

@lefb766
Copy link
Author

lefb766 commented Aug 27, 2017

Should be ready for review now. @mhegazy can you take a look?

I've selectively adopted @tycho01 's work.

Note: #6524 can also be closed after merge this PR.

@microsoft microsoft deleted a comment from msftclas Sep 26, 2017
@microsoft microsoft deleted a comment from msftclas Sep 26, 2017
@KiaraGrouwstra
Copy link
Contributor

@mhegazy: conflict aside, is there more that could be done to improve this PR?

@typescript-bot
Copy link
Collaborator

Thanks for your contribution. This PR has not been updated in a while and cannot be automatically merged at the time being. For housekeeping purposes we are closing stale PRs. If you'd still like to continue working on this PR, please leave a message and one of the maintainers can reopen it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants