Title: Design Meeting Notes, 1/6/2023 · Issue #52141 · microsoft/TypeScript · GitHub
Open Graph Title: Design Meeting Notes, 1/6/2023 · Issue #52141 · microsoft/TypeScript
X Title: Design Meeting Notes, 1/6/2023 · Issue #52141 · microsoft/TypeScript
Description: Stricter Relational Comparison Operators #52036 #52048 When narrowed to Promise, we reject comparisons with a number. We use the comparable relationship to determine if we can compare two types. It is optimistic and roughly checks if one...
Open Graph Description: Stricter Relational Comparison Operators #52036 #52048 When narrowed to Promise, we reject comparisons with a number. We use the comparable relationship to determine if we can compare two types. It...
X Description: Stricter Relational Comparison Operators #52036 #52048 When narrowed to Promise, we reject comparisons with a number. We use the comparable relationship to determine if we can compare two types. It...
Opengraph URL: https://github.com/microsoft/TypeScript/issues/52141
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Design Meeting Notes, 1/6/2023","articleBody":"# Stricter Relational Comparison Operators\r\n\r\nhttps://github.com/microsoft/TypeScript/issues/52036\r\nhttps://github.com/microsoft/TypeScript/pull/52048/\r\n\r\n* When narrowed to `Promise`, we reject comparisons with a `number`.\r\n* We use the comparable relationship to determine if we can compare two types. It is optimistic and roughly checks if one operand has overlap with the other - and allows a `Promise | number` to be compared with a `number`.\r\n* Recurring issue - discussed in the past\r\n * https://github.com/microsoft/TypeScript/issues/5156\r\n * https://github.com/microsoft/TypeScript/issues/10120\r\n* Is it meaningful to allow `\u003e=` when you have an object?\r\n * Feels like it's questionable.\r\n* Can you get away with just restricting to `number`s and `bigint`s?\r\n * `string`s!\r\n* \"We have to be more choosier when checking for overlappiness\"\r\n* Kind of want to figure out a strategy where we get the base primitive type of each operand and then check if they're assignable to `bigint | number`, or `string`, and both have overlap.\r\n * Probably some subtlety - make sure to test with generics.\r\n\r\n\r\n# Improved Logic When Choosing Between Covariant and Contravariant Inferences\r\n\r\nhttps://github.com/microsoft/TypeScript/issues/52111#issuecomment-1372986298\r\nhttps://github.com/microsoft/TypeScript/pull/52123\r\n\r\n```ts\r\ninterface A { a: string }\r\ninterface B extends A { b: string }\r\ninterface C extends A { c: string }\r\n\r\ndeclare function cast\u003cT, U extends T\u003e(x: T, test: (x: T) =\u003e x is U): U;\r\n\r\ndeclare function isC(x: A): x is C;\r\n\r\nfunction f1(a: A, b: B) {\r\n const x1 = cast(a, isC); // cast\u003cA, C\u003e\r\n const x2 = cast(b, isC); // cast\u003cA, C\u003e\r\n // ~~~\r\n // Argument of type '(x: A) =\u003e x is C' is not assignable to parameter of type '(x: B) =\u003e x is B'.\r\n // Type predicate 'x is C' is not assignable to 'x is B'.\r\n // Property 'b' is missing in type 'C' but required in type 'B'.\r\n}\r\n```\r\n\r\n* When doing type argument inference, we separate covariant inference sites from contravariant inference sites.\r\n * When deciding on what to infer, we use these to prioritize.\r\n * We try to pick covariant inferences, and by default construct a type from covariant inference candidates.\r\n * We *do not* use this type constructed by covariant inferences if:\r\n * the constructed type is `never`, or\r\n * it's not a subtype of *any* contravariant inference candidate.\r\n * *\\[Editor's Note]: The intuition here is that a contravariant inference site places a hard expectation on what it can be given; if that fails, using the contravariant inference will provide a better error message.*\r\n * #52123 added *another* exception here where we *do not* do this when the type parameter is used as a constraint of another type parameter *and* for that constrained type parameter, its covariant inference candidates the constructed covariant type of its constraint (i.e. the original type parameter).\r\n * So now in the assignment to `x2`, we choose the type `A` instead of `C` because `T` is used as the constraint of `U`, and the candidate of `A` would not have been assignable to \r\n* When a covariant inference is a subtype of the contravariant inference, you have a range of types you can choose from.\r\n* Doesn't solve all possible variations of this - doesn't fix the case of arbitrarily nested generic constraints.\r\n\r\n# Varying Subtype Reduction Depending on Declaration Order\r\n\r\nhttps://github.com/microsoft/TypeScript/issues/52100\r\n\r\n```ts\r\ndeclare let u: Promise\u003cunknown\u003e\r\ndeclare let a: Promise\u003cany\u003e\r\n\r\n// Assigned an expression that is Promise\u003cany\u003e | Promise\u003cunknown\u003e\r\n// but that will undergo subtype reduction\r\n// The type of union depends on whether a or u was declared first\r\nlet union =\r\n// ^?\r\n// Varies between 'Promise\u003cany\u003e' and 'Promise\u003cunknown\u003e'.\r\n Math.random() \u003e 0.5\r\n ? Promise.reject\u003cany\u003e()\r\n : Promise.reject\u003cunknown\u003e();\r\n\r\nunion.then(v =\u003e v.toString());\r\n```\r\n\r\n* These differ by type ID based on where they're declared in the file and get sorted in an initial union type.\r\n* When we try to reduce the union, whichever came first \"wins\" because `any` and `unknown` are both (non-strict) subtypes of each other.\r\n* Unclear if you'd want `unknown` or `any` to win out. Presumably first principles would indicate `unknown` because it's the safer one.\r\n* Don't really have any solution here. Many similar issues show up.\r\n\r\n# Monomorphism Recap - Runtime Speed vs. Memory Usage\r\n\r\nhttps://github.com/microsoft/TypeScript/pull/51682\r\nhttps://github.com/microsoft/TypeScript/pull/51880 \r\n\r\n* We got some nice performance boosts from ensuring definite shapes on certain Nodes and Symbols - but it came at the expense of memory.\r\n* Feels like a good tradeoff in general.\r\n* We can start shrinking many of the types we have in the compiler - lots of optional boolean properties.\r\n * But V8 allocates in chunks - so this work could be for nothing.\r\n * Still buys us some wiggle room, more possibility to shrink down the line.\r\n* Can we just shrink down `Identifier` to 2 properties?\r\n * 2 *additional* properties on top of `Node`.\r\n * We can try.\r\n * Get rid of `originalKeywordKind`\r\n * Move `hasExtendedUnicodeEscape` to the containing source file, turn it into a slow path during emit.\r\n * Move emit-related things into their own bucket.\r\n","author":{"url":"https://github.com/DanielRosenwasser","@type":"Person","name":"DanielRosenwasser"},"datePublished":"2023-01-07T18:07:47.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/52141/TypeScript/issues/52141"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:2a7f663b-fe90-e55f-7138-4fcc51789604 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BF40:EB829:1D3CE7:28E2A5:6A623147 |
| html-safe-nonce | 3b8d8d5682d680919be01b7a6e588ebe2ac45c0f1ebe45723c4293b6303504d6 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRjQwOkVCODI5OjFEM0NFNzoyOEUyQTU6NkE2MjMxNDciLCJ2aXNpdG9yX2lkIjoiMzY1NDE2ODM5NDk0ODgxNzIyMyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 305367b522c3a0d0b72ddf2e0450d82b75a24d2c6da4efa3f9e35b398a2fc57c |
| hovercard-subject-tag | issue:1524029201 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/microsoft/TypeScript/52141/issue_layout |
| twitter:image | https://opengraph.githubassets.com/ad39fb6e807e76b8971a8c6735db64cd221ba8d2b1c53e49f298cbd1808849c4/microsoft/TypeScript/issues/52141 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/ad39fb6e807e76b8971a8c6735db64cd221ba8d2b1c53e49f298cbd1808849c4/microsoft/TypeScript/issues/52141 |
| og:image:alt | Stricter Relational Comparison Operators #52036 #52048 When narrowed to Promise, we reject comparisons with a number. We use the comparable relationship to determine if we can compare two types. It... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | DanielRosenwasser |
| hostname | github.com |
| expected-hostname | github.com |
| None | f01037538d0c99e88fa8e01da1b1825ad354ff4da745198c7392a43592c8398c |
| turbo-cache-control | no-preview |
| go-import | github.com/microsoft/TypeScript git https://github.com/microsoft/TypeScript.git |
| octolytics-dimension-user_id | 6154722 |
| octolytics-dimension-user_login | microsoft |
| octolytics-dimension-repository_id | 20929025 |
| octolytics-dimension-repository_nwo | microsoft/TypeScript |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 20929025 |
| octolytics-dimension-repository_network_root_nwo | microsoft/TypeScript |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 10b5a8861bf21b66a650f894089f8ce1476c1d49 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width