microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.83k stars 12.46k forks source link

Use Generic from method in Generic from interface #38312

Closed y-nk closed 4 years ago

y-nk commented 4 years ago

TypeScript Version: 3.8.3

Search Terms: "generic in generic"

Expected behavior:

Should be able to pass one generic to an other generic

Actual behavior:

Generic cannot cascade down to one an other

Related Issues: the well known #1213

Notes: I'm still posting this although #1213 is still open, knowingly. I've read the entire thread of #1213. It has been commented massively, with lots of good proposals and upvoted more than ~600 times (if you combine all). The last post I could identify (i don't know everyone) from core contributors is a 2016 feedback (from @RyanCavanaugh) on a 2015 comment marking the proposal as "Quasi-approved" 5 years ago ; since then, there's no communication on this feature (rather decisions to move it some places, like "community backlog" or "Roadmap June 2019") and i think i'm not alone waiting for this to be able to complete my work with TS - or should i just drop it?

I don't claim this issue to be new, and it should easily marked as duplicate. I just hope this will help gather attention again on #1213 and hopefully a resolution of this before the end of 2025.

Code

type LocalStrategy = "local"
type FacebookStrategy = "facebook"

type Strategy = LocalStrategy | FacebookStrategy

type StrategyParameters<S extends Strategy> = (
    S extends LocalStrategy ? { email: string, password: string } :
    S extends FacebookStrategy ? { fbid: string } :
    never
)

interface Passport<S extends Strategy = Strategy> {
    type: S,
    parameters: StrategyParameters<S>
}

type DatabaseDocument<Model extends object> = { id: string } & Model

type DatabasePassport<S extends Strategy = Strategy> = DatabaseDocument<Passport<S>>

// could be extended by user later on
interface PassportApi<P extends DatabasePassport> {
    findByStrategy<S extends Strategy>(strategy: S): P<S>
}
Output ```ts "use strict"; ```
Compiler Options ```json { "compilerOptions": { "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "strictBindCallApply": true, "noImplicitThis": true, "noImplicitReturns": true, "useDefineForClassFields": false, "alwaysStrict": true, "allowUnreachableCode": false, "allowUnusedLabels": false, "downlevelIteration": false, "noEmitHelpers": false, "noLib": false, "noStrictGenericChecks": false, "noUnusedLocals": false, "noUnusedParameters": false, "esModuleInterop": true, "preserveConstEnums": false, "removeComments": false, "skipLibCheck": false, "checkJs": false, "allowJs": false, "declaration": true, "experimentalDecorators": false, "emitDecoratorMetadata": false, "target": "ES2017", "module": "ESNext" } } ```

Playground Link: Provided

RyanCavanaugh commented 4 years ago

There are currently nearly two thousand open Suggestions in this repo; even if we implemented one during every business day for the forseeable future, we wouldn't be done by 2025. It's understandable to want the language to be complete with all features you'd want to have, but do understand that 7-8 years is quite young for a programming language, and we grow TS slowly with intention to make sure it's something we can build on for a long time to come.

As I said in that issue, we'd like someone to put up a proof of concept PR for us to evaluate next steps. In terms of the core team's priorities, we haven't found these scenarios to be higher priority than the work we've decided to implement ourselves in terms of unblocking different programming paradigms. You can help us to prioritize work by talking about concrete scenarios you'd like to solve and how the proposed suggestion would efficiently address that.

typescript-bot commented 4 years ago

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

y-nk commented 4 years ago

@RyanCavanaugh thanks for the honest answer. Just for the sake of answering back (because you took some time for it), I do understand that everything takes time and there are priorities. I honestly lack of a wider view to appreciate the priorities and challenges of the project right now and i do like something going slow and steady rather than moving too fast and breaking often. Nevertheless it seemed (to me) like those numbers (600+ reactions, 5 years open) were big enough to at least be considered in the backlog and not left for contributions.

Mind this : if there's no contributions proposed/drafted, maybe it's not that no-one wants to do it, but rather that no-one willing to to do it actually understands how to achieve the task (i'm one of the last kind - i've forked the repo, tried my best and failed)

As for the contribution part, my scenario piles up with dozens of already provided scenarios of abstraction of types. The code given in the issue is one i intented to push to production, but i've decided to withdraw this project from going opensource due to this lack of feature from the TS side.