Skip to content

Add the comparability relationship to the spec (attempt two) #20686

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
wants to merge 2 commits into from

Conversation

DanielRosenwasser
Copy link
Member

Fixes #17214.
Subsumes #17215.

@DanielRosenwasser
Copy link
Member Author

I don't know if I covered this feedback:

  • if M has a this-parameter whose type is not the void type, then it must be comparable to the this-parameter type of N or N must not have a this-parameter.

* *T* is an enum member type, *S* is a literal type, and the literal values of *S* and *T* are identical.
* *S* is a literal type and *T* is the base primitive type of *S*.
* *T* is a literal type and *S* is the base primitive type of *T*.
* *S* is a union type and some constituent type of *S* is comparable to *T*.
Copy link
Member

Choose a reason for hiding this comment

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

Is this relation 100% symmetric? Can we just say that up front and cut this in half?

Copy link
Member

@RyanCavanaugh RyanCavanaugh Dec 13, 2017

Choose a reason for hiding this comment

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

Or even if it's not, parcel out the symmetric relations, e.g. S is assignable to T if any of the following are true for S* = S, T* = T or for S* = T, T* = S... (all symmetric properties here in terms of S* / T*)

Copy link
Member Author

Choose a reason for hiding this comment

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

@RyanCavanaugh I don't quite understand what you mean. But I'd prefer not to combine these operations so that a reader (or a spec writer 😉) can manually do a diff between the assignability and comparability sections on their own

* the non-primitive object type is comparable to and from any other object type, and
* when relating any two signatures, each signature is always instantiated using type Any for all type arguments.

While the comparable relation is often applied bidirectionally on a pair of types, it is not a symmetric relationship.
Copy link
Member

Choose a reason for hiding this comment

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

Answers my above question but deserves a counterexample

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.

Some comments so far.

* *S* is an enum type and *T* is the primitive type Number.
* *S* is the Never type.
* *S* is the Undefined type and *T* is the Void type.
* *S* is either the Undefined or Null type, and strict null checks ([#strict-null-checks]) are disabled.
Copy link
Member

Choose a reason for hiding this comment

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

I thought we weren't talking about non-strict in the spec.

Copy link
Member Author

Choose a reason for hiding this comment

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

You already used this in your other PR :(

* *S* is a numeric enum or numeric enum member type and *T* is the primitive type Number.
* *S* and *T* are both enum member types with respective containing enum types *E* and *F* and
* *E* is a subtype of *F*.
* *S* and *T* are both non-const enum types with the same declared name, and
Copy link
Member

Choose a reason for hiding this comment

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

need to bind E and F here too

* *E* is a subtype of *F*.
* *S* and *T* are both non-const enum types with the same declared name, and
* for each enum member *M* in *E*, there exists an enum member declaration *N* in *F* such that *M* and *N* have the same declared name and value.
* *S* is an enum member type, *T* is a literal type, and the literal values of *S* and *T* are identical.
* *S* is a string literal type and *T* is the primitive type String.
* *S* is a union type and each constituent type of *S* is a subtype of *T*.
* *S* is an intersection type and at least one constituent type of *S* is a subtype of *T*.
* *T* is a union type and *S* is a subtype of at least one constituent type of *T*.
* *T* is an intersection type and *S* is a subtype of each constituent type of *T*.
Copy link
Member

Choose a reason for hiding this comment

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

excess property checks?

Copy link
Member Author

Choose a reason for hiding this comment

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

Already taken care of above in the intro to the section.


*TODO: Document the base primitive type.*

Types are required to be *comparable* in certain circumstances, such as part of when checking whether two values of given types might be equal at runtime using operators like '===', or when using a type assertion.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this list be complete and authoritative? I don't think it's going to be defined elsewhere. And based on your findings, it looks like it already is complete, it just needs to say that these are the only places that comparability happens.

* *S* is either the Undefined or Null type, and strict null checks ([#strict-null-checks]) are disabled.
* *S* is an object type and *T* is the non-primitive `object` type.
* *T* is an object type and *S* is the non-primitive `object` type.
* *S* or *T* is a numeric enum or numeric enum member type and the other is the primitive type Number.
Copy link
Member

Choose a reason for hiding this comment

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

This applies to strings too, doesn't it?

* *S* is an intersection type and at least one constituent type of *S* is comparable to *T*.
* *T* is a union type and *S* is comparable to at least one constituent type of *T*.
* *T* is an intersection type and *S* is comparable to each constituent type of *T*.
* *T* is a type parameter and *S* is a mapped type *{ [P in keyof X]: Y }*, and *Y* is comparable to *X[P]*.
Copy link
Member

Choose a reason for hiding this comment

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

I think that you have to say that X is comparable (or identical?) to T if you don't just use keyof T in the mapped type itself.

* *S* is a key query type *keyof S'* and *T'* is comparable to *S'*.
* *S* is comparable to *keyof C* where *C* is the constraint of *S*.
* *T* is an indexed access type *T'[K]* and *S* is comparable to *C[K]* where *C* is the constraint of *T'*.
* *T* is a mapped type *{ [P in K]: X }*, *S* is not a mapped type, *keyof S* is identical to *K*, and *S[K]* is comparable to *X*.
Copy link
Member

Choose a reason for hiding this comment

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

the last clause should be S[P] is comparable to X, not S[K].

@DanielRosenwasser DanielRosenwasser force-pushed the comparability-spec-update branch from 7ebb064 to 1c5bdd3 Compare December 15, 2017 00:58
@DanielRosenwasser DanielRosenwasser force-pushed the comparability-spec-update branch from 1c5bdd3 to 2fb84d5 Compare December 15, 2017 00:58
@mhegazy mhegazy added the Spec Issues related to the TypeScript language specification label Jan 5, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Mar 29, 2018

@DanielRosenwasser can we get these in?

@RyanCavanaugh
Copy link
Member

@DanielRosenwasser I would like to have this and its friends be merged or closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Spec Issues related to the TypeScript language specification
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants