Title: First class type constructor · Issue #35816 · microsoft/TypeScript · GitHub
Open Graph Title: First class type constructor · Issue #35816 · microsoft/TypeScript
X Title: First class type constructor · Issue #35816 · microsoft/TypeScript
Description: Search Terms first class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic-generics higher-kinded-types hrt higher...
Open Graph Description: Search Terms first class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic...
X Description: Search Terms first class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic...
Opengraph URL: https://github.com/microsoft/TypeScript/issues/35816
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"First class type constructor ","articleBody":"\u003c!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨\r\n\r\nHalf of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker.\r\n\r\nPlease help us by doing the following steps before logging an issue:\r\n * Search: https://github.com/Microsoft/TypeScript/search?type=Issues\r\n * Read the FAQ, especially the \"Common Feature Requests\" section: https://github.com/Microsoft/TypeScript/wiki/FAQ\r\n\r\n--\u003e\r\n\r\n## Search Terms\r\nfirst class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic-generics higher-kinded-types hrt higher kinded rank types rank-n\r\n\r\n\u003c!-- List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily --\u003e\r\n\r\n## Suggestion\r\nAdd first class type constructor support \r\n\r\n\u003c!-- A summary of what you'd like to see added or changed --\u003e\r\n\r\n### This proposal contains the following features\r\n- HKT (Higher Kinded Types)\r\n- Variadic Generics\r\n- Independent type constructor\r\n- Transitivity of type constructor\r\n\r\n### HKT \r\n\r\n```ts\r\ninterface Functor\u003cF extends type\u003cT\u003e\u003e {\r\n map\u003cA, B\u003e(f: (a: A) =\u003e B, s: F\u003cA\u003e): F\u003cB\u003e\r\n}\r\n```\r\n \r\nThe following uses this `'type' ('\u003c' \u003cargs\u003e,+ '\u003e')? \u003creturn\u003e?` syntax \r\nalthough this syntax has compatibility issues\r\n\r\nThis is already very useful, but there are many other problems\r\n\r\n### Transitivity \u0026 Independence\r\n ```ts\r\ndeclare function foo\u003cT\u003e(v: T): T\r\ntype params = Parameters\u003ctypeof foo\u003e // type params = [v: unknown]\r\ntype rets = ReturnType\u003ctypeof foo\u003e // type rets = unknown\r\n ```\r\n\r\n[Playground](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtVJxwB4AVAPgAoA3ALnhIEo6SBYAKAwE8AHBb2KAFsAzvAC88AAoDBIDCBjCiXXjkQEcZdioRwMoiQCU5yGKhI8Qyy2o1kgA)\r\n \r\nBecause it is not transitive, generics are discarded during inference, \r\nso we need the type constructor to be transitive, \r\nand this requires that the type constructor must be independent\r\n\r\nwith transitivity and independence, this will be \r\n\r\n```ts\r\ndeclare function foo\u003cT\u003e(v: T): T\r\ntype params = Parameters\u003ctypeof foo\u003e // type params = type\u003cT\u003e [v: T]\r\ntype rets = ReturnType\u003ctypeof foo\u003e // type rets = type\u003cT\u003e T\r\n```\r\n\r\nIndependent type constructor should not exist at runtime, \r\nso when an independent type constructor is used as a type without being applied, \r\nthe generic type should be discarded again\r\n\r\n```ts\r\nlet a: ReturnType\u003ctypeof foo\u003e\u003c1\u003e // let a: 1\r\nlet b: Parameters\u003ctypeof foo\u003e\u003c1\u003e // let b: [v: 1]\r\n\r\nlet c: ReturnType\u003ctypeof foo\u003e // let c: unknown\r\nlet d: Parameters\u003ctypeof foo\u003e // let d: [v: unknown]\r\n```\r\n\r\nThe transitivity of type constructors should also exist on type aliases\r\n\r\n```ts\r\ntype params = type\u003cT\u003e [v: T] // type params\u003cT\u003e = [v: T]\r\ntype rets = type\u003cT\u003e T // type rets\u003cT\u003e = T\r\n```\r\n\r\n\\* \r\nThis `type` syntax is very loose, \r\nYou can represent not only type constructors with parameters, \r\nbut also type constructors without parameters, \r\nor you can optionally fill in the return type in the type parameter \r\n\r\n```ts\r\ntype num = type number // type num = number\r\n```\r\n```ts\r\ntype Foo\u003cT extends type\u003cA, B\u003e A | B\u003e = T\r\n// This means T extends type\u003cA, B\u003e =\u003e R where R extends A | B\r\n// or like associated-types in rust | swift\r\n// type\u003cA, B\u003e {\r\n// type R: A | B\r\n// }\r\n\r\ntype Bar\u003cT extends type\u003cA\u003e\u003e = T\r\n// For external T extends type\u003cA\u003e =\u003e unknown\r\n// For internal T extends type\u003cA\u003e =\u003e anonymous nominal unique type\r\n```\r\n\r\n### Variadic Generics\r\n\r\nThe current improvised solution is \r\n\r\n```ts\r\ntype Foo\u003cT extends any[]\u003e = T\r\n```\r\n\r\nNormally this is enough, but it is not free enough when the type constructor is transitive \r\nif has variadic generics, then the type constructor can be inferred \r\n\r\n- Variadic syntax\r\n ```ts\r\n type Foo\u003c...T extends any[]\u003e = T\r\n\r\n type Bar = Foo\u003c1, 2, 3\u003e // type Bar = [1, 2, 3]\r\n ```\r\n\r\n- Infer TypeReturnType\r\n ```ts\r\n type TypeReturnType\u003cT extends type\u003c...A extends any[]\u003e any\u003e =\r\n T extends type\u003c...A extends any[]\u003e infer R ? R : never\r\n\r\n interface Foo\u003cT\u003e { a: T }\r\n type Bar\u003cA, B\u003e = A | B\r\n\r\n type use = TypeReturnType\u003cFoo\u003e // return type\u003cT\u003e { a: T } or return Foo\r\n type use = TypeReturnType\u003cBar\u003e // return type\u003cA, B\u003e A | B\r\n ```\r\n- Infer TypeParameters\r\n ```ts\r\n type TypeParameters\u003cT extends type\u003c...A extends any[]\u003e any\u003e =\r\n T extends type\u003c...A extends infer P\u003e any ? P : never\r\n\r\n type Foo\u003cA, B\u003e = any\r\n\r\n type use = TypeParameters\u003cFoo\u003e // return type\u003cA, B\u003e [A, B]\r\n ```\r\n\r\n### Compatibility\r\n\r\nIt is a pity that although this `type` syntax is very readable, it has compatibility issues \r\n\r\n```ts\r\ntype type = 1\r\ntype foo = type\r\n```\r\n\r\nOther possible syntax\r\n\r\n```ts\r\ntype A = type: any\r\ntype A = type\u003cB\u003e: any\r\n\r\ntype A = type: any\r\ntype A = type:\u003cB\u003e any\r\n\r\ntype A = (type = any)\r\ntype A = (type\u003cB\u003e = any)\r\n\r\ntype A = ~any\r\ntype A = ~\u003cB\u003eany\r\n\r\ntype A = any\r\ntype A = \u003cB\u003eany\r\n\r\ntype A = for any\r\ntype A = for\u003cB\u003e any\r\n```\r\n\r\n### What is First class Type constructor\r\n\r\n`* -\u003e *` is type constructor \r\n`(* -\u003e *) -\u003e *` is HKT \r\n`* -\u003e * -\u003e *` is binary type constructor with currying\r\n`(* -\u003e *) -\u003e (* -\u003e *)` is first class type constructor without currying but with transitivity, independent\r\n\r\n## Examples\r\n\r\n```typescript\r\ninterface Monad\u003cT extends type\u003cX\u003e\u003e {\r\n map\u003cA, B\u003e(f: (a: A) =\u003e B): T\u003cA\u003e =\u003e T\u003cB\u003e\r\n lift\u003cA\u003e(a: A): T\u003cA\u003e\r\n join\u003cA\u003e(tta: T\u003cT\u003cA\u003e\u003e): T\u003cA\u003e\r\n}\r\n```\r\n\r\n```typescript\r\nfunction mixin\u003cB extends type\u003c...P extends any[]\u003e new (...a: any[]) =\u003e any\u003e(Base: B) {\r\n return class\u003c...P extends TypeParameters\u003cB\u003e\u003e extends Base\u003c...P\u003e { }\r\n}\r\nclass A\u003cT\u003e { }\r\nclass B\u003cT\u003e extends mixin(A)\u003cT\u003e { }\r\n```\r\n\r\n\u003c!-- Show how this would be used and what the behavior would be --\u003e\r\n\r\n## Checklist\r\n\r\nMy suggestion meets these guidelines:\r\n\r\n* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code\r\n* [x] This wouldn't change the runtime behavior of existing JavaScript code\r\n* [x] This could be implemented without emitting different JS based on the types of the expressions\r\n* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)\r\n* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).\r\n\r\n## Reference\r\n\r\n#1213 \r\nhttps://github.com/microsoft/TypeScript/issues/1213#issuecomment-370763683 \r\n#5959 \r\n#29904 \r\n#30215 \r\n#31116 \r\n#41040 \r\n#44875 \r\n#48036 \r\n#48820 \r\n\r\n[first-class-protocols](https://github.com/michaelficarra/proposal-first-class-protocols) \r\n","author":{"url":"https://github.com/2A5F","@type":"Person","name":"2A5F"},"datePublished":"2019-12-21T07:05:54.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/35816/TypeScript/issues/35816"}
| 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:52170c7d-27e5-2f9e-5bd5-28fdb1e1ba2b |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E40C:3932F6:3BCD52:568D97:6A6220E2 |
| html-safe-nonce | 3f0cd40280a133c9572d1d9b702fceb255731569011ea4b6f219e5e94bf9fd4a |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFNDBDOjM5MzJGNjozQkNENTI6NTY4RDk3OjZBNjIyMEUyIiwidmlzaXRvcl9pZCI6Ijg0MjYwODc2Njk0NDA3MzgiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 330889a5b4b4a45125740ab7aa5dd1968284bc699f16172dc1fcc719d70941a2 |
| hovercard-subject-tag | issue:541294350 |
| 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/35816/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c3ce1800cddd2b30cd07075b09d7112431e2f40dcfaf6da3301ae214f2e5426d/microsoft/TypeScript/issues/35816 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c3ce1800cddd2b30cd07075b09d7112431e2f40dcfaf6da3301ae214f2e5426d/microsoft/TypeScript/issues/35816 |
| og:image:alt | Search Terms first class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | 2A5F |
| hostname | github.com |
| expected-hostname | github.com |
| None | be68eaf9abf2a202afbd94047d7200fb88b7edb0338f533bf171bbb1a69fab4e |
| 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 | 3d00b04c8874615454dfbdb32a7d2ca4db66d3f4 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width