Title: Context sensitive inference fails with class instance · Issue #62380 · microsoft/TypeScript · GitHub
Open Graph Title: Context sensitive inference fails with class instance · Issue #62380 · microsoft/TypeScript
X Title: Context sensitive inference fails with class instance · Issue #62380 · microsoft/TypeScript
Description: 🔎 Search Terms "intra expression inference class", "context sensitive class inference" 🕗 Version & Regression Information This is the behavior in every version I tried, and I reviewed the FAQ for entries about context sensitive inference...
Open Graph Description: 🔎 Search Terms "intra expression inference class", "context sensitive class inference" 🕗 Version & Regression Information This is the behavior in every version I tried, and I reviewed the FAQ for e...
X Description: 🔎 Search Terms "intra expression inference class", "context sensitive class inference" 🕗 Version & Regression Information This is the behavior in every version I tried, and ...
Opengraph URL: https://github.com/microsoft/TypeScript/issues/62380
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Context sensitive inference fails with class instance","articleBody":"### 🔎 Search Terms\n\n\"intra expression inference class\", \"context sensitive class inference\"\n\n### 🕗 Version \u0026 Regression Information\n\n- This is the behavior in every version I tried, and I reviewed the FAQ for entries about context sensitive inference\n\n### ⏯ Playground Link\n\nhttps://www.typescriptlang.org/play/?#code/MYGwhgzhAEBiD28A8AVAfNA3gWAFDWmHgDsIAXAJwFdgz4KAKAByoCMQBLYaD44gUwoAuaCgCUWAL55puPKEgwAQmAoBhcFFQYc+QiXLVa9Zm07cwwYPyj0RDcmDL8R46AF4MrRCH5hiEpiysni6BAD04aIAFhwwcdAAtgCe0JZkVGAg0EwU8AAmNGQcJNBUEPyEkPwANNDEqnkA7vz50PnwTcQAdHgRUQAGrKoQAzww-mkUFGCp8ABmhJrxpGT+1jBNHGTRadAA5vwCFFw8xPOCFK3Q83mJfdCR+sTOAB5k0As5VwBuJeU3KjEWglYhVEAgCC9PQKKDQNQkNa8QRINR1WA6B4EIirIx0RhYgg5MynWivERowkEFjsU7zRCwdL0ZL2MkUiSeOA1KnE2ncYYUCAiFTqZZIDEAbQAuty9ARArICCEYQYPjikccPPV+E14YiwMiCXLoAAWABMsqJhDIrw8GAEuoQ8AYmDSpBawmttskYktRIlDugIo0igca2cduglCo-DEMsJTytSYIAD0APwJqKOCMJIEAa2InWIDzEMjwoQeTxQ0UquXg7H4iWg-FecTIm22uzA0AgvH2VHAFDOjmBlS+O0qsJg0U6-B+gmh2OWepeBuOqPRmONOMMRRMPJp5i9FL9VsPdIZTIoLOgDDZ8I5GFgp6J5-5qmFqhDWgxL4VD2VbFVWeDVBAAdU7eAqDIABBPh4HDUEtUDBFV0NBhCXNF8yUjQMnRdN0IA9EQcJ9F9A2DZYwycSpOWjWMX0TZMiXTTMe3DSpc2IAsixLcsVVWEC13Azs4MLRDSncbVdVQ0CjStLDCTvG0RGIKhElYQRH2kuBEAI-wiMEEibWgMjHiiSYWyYcxtijZImEqfxxKcJDShwmsrhuDhXhsKMa3GCAYzONIISqCoIDqVhoPGYgAHIPlydIuCyG56CSVIYIABQASTKCowv4QkKK-Kjs1ojB6N9NjmJYjNjSeMrxl05BXQM4j6nUzSh0kNA+NwZUwnM6AAAkwD+Yh9j2eYr1SeYgRBUoth2ep4CmftEiOdt2ngGw4o+GsQCYB4pxXOSNzgLcrR3aNjHkpM32PeEX2pEluHpeBGVum9lPJB9I2fA9XugAVPvxb7tMoxRxTQP8pAA-igME9VhKHKSUP1dDMItQkcM5PC9Na90jK9UyquNBhtOK0VQ0aujqAY6qauY1j6qzDimvzQsuj6gbKyiGCbhmwFgWKRbOz2QpEhSNb1M26AAH0OhseXoCaeg82O5dZJR86MSwHHVTxfdjRevlHspE3eSPd7QeZVkVL+zkActh6QZm+xJZSVS5y0yNIZ-GHCX-PRAOecghMNCCdgAEXU6W0Z1U6UYw41FO3Ey8cT-DCcMz1SLJq1PdSTPdX9iBqIjOmYwLokmKZmqWatBr2YSJ0kBz9q1I0wRTN6vRSzkPQnhnFp5yHDhFgndo49SVR1rluI9pyRRWjqWylYgJe1YoDWBPD5HI87MC8gmmCTjIYudO1zHU+x9PbRL5r9KJvOTLIpTKcTsuK-KqN6Zr-o9dmZ1SbmzGiHNuJc2LP3Msg9BoXwckGVQAB5VgAArfgtBtBakGgQSwGwIB2FvGVVw2lvDwF8P4eGg9AECyuP2Qcnx0GYI+AkXgFxpjXCIJw2gIBkiLiWIoJOhpdaXSJNdI2d0zxA3vBbZMD0bbu1vLI7Szt5FAwFJ+CgqCMFYN-EHOGIcEZhzVBjTUCcZJmMECnBSd8roZ3tFnAmhF2r5xfK1KwNhCGelphVemplGJRCZo3WuYCcwwDbh3YmXcuq9x5kAA\n\n### 💻 Code\n\n```ts\nclass Foo\u003cT\u003e {\n constructor(public inner: T) {}\n}\n\nclass BarClass\u003cT\u003e {\n constructor(public accessor: (state: T) =\u003e boolean) {}\n}\n\n{\n // This is my actual production use case, narrowed down.\n // `bars` is an array of class instances with a generic inferred from\n // context of previous function calls.\n class Container\u003cC, F\u003e {\n constructor(\n public ctx: C,\n public fooFactory: (ctx: C) =\u003e F,\n public bars: BarClass\u003cF\u003e[],\n ) {}\n }\n\n const container = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n [new BarClass(state =\u003e true)],\n // ^?\n // state is unknown\n )\n}\n\n{\n // The problem exists with a singular instance of the class however.\n class Container\u003cC, F\u003e {\n constructor(\n public ctx: C,\n public fooFactory: (ctx: C) =\u003e F,\n public bar: BarClass\u003cF\u003e,\n ) {}\n }\n\n const containerWithoutAnnotation = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n new BarClass(state =\u003e true),\n // ^?\n // state is unknown\n )\n\n const containerWithAnnotation = new Container(\n 42,\n (ctx: number) =\u003e new Foo({ answer: ctx }), // an explicit type annotation on ctx here fixes the issue\n new BarClass(state =\u003e true), // in all cases, but isn't practical for my API use case\n // ^?\n // state is Foo\u003c{ answer: number }\u003e\n )\n}\n\n{\n // Having a factory function with no arguments doesn't help\n class Container\u003cC, F\u003e {\n constructor(\n public ctx: C,\n public fooFactory: (ctx: C) =\u003e F,\n public barFactory: () =\u003e BarClass\u003cF\u003e,\n ) {}\n }\n\n const container = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n () =\u003e new BarClass(state =\u003e true),\n // ^?\n // state is unknown\n )\n}\n\n{\n // A factory function with a dummy argument _does_ work\n class Container\u003cC, F\u003e {\n constructor(\n public ctx: C,\n public fooFactory: (ctx: C) =\u003e F,\n public barFactory: (dummy: never) =\u003e BarClass\u003cF\u003e,\n ) {}\n }\n\n const containerWithDummy = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n dummy =\u003e new BarClass(state =\u003e true),\n // ^?\n // state is Foo\u003c{ answer: number }\u003e\n )\n\n // however if the dummy argument isn't passed, it doesn't work\n const containerWithWrongArity = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n () =\u003e new BarClass(state =\u003e true),\n // ^?\n // state is unknown\n )\n}\n\n{\n type BarObject\u003cT\u003e = {\n accessor: (state: T) =\u003e boolean\n }\n\n // A regular object is inferred correctly.\n class Container\u003cC, F\u003e {\n constructor(\n public ctx: C,\n public fooFactory: (ctx: C) =\u003e F,\n public bar: BarObject\u003cF\u003e,\n ) {}\n }\n\n const container = new Container(\n 42,\n ctx =\u003e new Foo({ answer: ctx }),\n { accessor: state =\u003e true },\n // ^?\n // state is Foo\u003c{ answer: number }\u003e\n )\n}\n```\n\n\n### 🙁 Actual behavior\n\nThe BarClass type isn't inferred correctly.\n\n### 🙂 Expected behavior\n\nI think I'd expect BarClass to be inferred in all those cases? Except perhaps when the dummy argument is in the function signature, but the passed function has the wrong arity. \n\n### Additional information about the issue\n\nUnder the umbrella of https://github.com/microsoft/TypeScript/issues/47599\n\nThis PR+comment feels close https://github.com/microsoft/TypeScript/pull/54183#pullrequestreview-1947535738","author":{"url":"https://github.com/Mike-Dax","@type":"Person","name":"Mike-Dax"},"datePublished":"2025-09-02T09:53:23.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/62380/TypeScript/issues/62380"}
| 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:f1cb42a0-f3bf-ddb6-4be6-7582cf304590 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 83E0:183EB6:65A6E3:8C86B7:6A618582 |
| html-safe-nonce | f770a559111602cfc8afd5152f578808b4813ebdc6d19fab9dc946ca91d59adb |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4M0UwOjE4M0VCNjo2NUE2RTM6OEM4NkI3OjZBNjE4NTgyIiwidmlzaXRvcl9pZCI6Ijc3NDkyNjI2NDkwMjU3MjU4MjYiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 31ccd00aa01fe75c9db25772d6008a354573b180033207522474323f375f436c |
| hovercard-subject-tag | issue:3375291960 |
| 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/62380/issue_layout |
| twitter:image | https://opengraph.githubassets.com/9f9db26a94e1fcdcd593ee5df0753f6bd10e822d872c5417f21d8b6bfbd0af6f/microsoft/TypeScript/issues/62380 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/9f9db26a94e1fcdcd593ee5df0753f6bd10e822d872c5417f21d8b6bfbd0af6f/microsoft/TypeScript/issues/62380 |
| og:image:alt | 🔎 Search Terms "intra expression inference class", "context sensitive class inference" 🕗 Version & Regression Information This is the behavior in every version I tried, and I reviewed the FAQ for e... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Mike-Dax |
| hostname | github.com |
| expected-hostname | github.com |
| None | c28c2f6607f2aacbd934868d997038895c9780d08babfe918550d73773326f4c |
| 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 | cd05235d52ffb3318513d883a56c87a121015c8b |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width