Skip to content

The inference when using the new keyword doesn't work as expected. #61621

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
1 task done
D0nte53 opened this issue Apr 27, 2025 · 4 comments
Closed
1 task done

The inference when using the new keyword doesn't work as expected. #61621

D0nte53 opened this issue Apr 27, 2025 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@D0nte53
Copy link

D0nte53 commented Apr 27, 2025

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

Hi, here’s my issue :

The inference when using the new keyword doesn't work as expected. I can't find a pattern that allows the types inferred by new to be the actual types inferred at instantiation, rather than just the types constrained by the class's generic parameters (e.g extends Record<string, string>)

ts-playground:

type t_Prisma<MNs extends Record<string, string> > = {
    ModelName: MNs
}


class Prisma1<P extends t_Prisma<MNs>, MNs extends Record<string, string>> implements t_Prisma<MNs> {
    _prisma: P;

    constructor(_prisma: P) {
        this._prisma = _prisma;
    }
    get ModelName() {
    return this._prisma.ModelName;
    }
}


class Prisma2<MNs extends Record<string, string>> implements t_Prisma<MNs> {
    _prisma: t_Prisma<MNs>;

    constructor(_prisma: t_Prisma<MNs>) {
        this._prisma = _prisma;
    }

    get ModelName() {
        return this._prisma.ModelName;
    }
}


const _Prisma = {
    ModelName:{
        Model1: "Model1",
        Model2: "Model2",
        Model3: "model3"
    } as const 
}

const prismaInstance1 = new Prisma1(_Prisma)
type test_ModelName1 = typeof prismaInstance1.ModelName

const prismaInstance2 = new Prisma2(_Prisma)
type test_ModelName2 = typeof prismaInstance2.ModelName

In the first code (Prisma1), the inference for ModelName doesn't work as expected (the inferred type is Record<string, string>), but it feels more natural.

In the second code (Prisma2), the inference works correctly ({Model1: "Model1", ...}), but it forces me to repeat the type t_Prisma<MNs> everywhere in the class definition , which is not ideal.

I really want to use the first pattern because it exactly represents what I want to do: parameterize a class with an object of type t_Prisma, but I'm not sure if it's a good practice since it doesn't work that way.

Thank you for your help and have a great day!

@MartinJohns
Copy link
Contributor

MartinJohns commented Apr 27, 2025

Constraints are not inference sites. So in your Prisma1 case there's nothing to infer the type of MNs from.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Apr 28, 2025

To add to the previous comment, using type parameters as if they are type aliases is generally not going to work out well, because the assumed intent is that they are indeed parameters. The second definition is the "correct" way to write a generic type, where you've pushed the type parameter down as low as it can go in the hierarchy, and you have as few as possible

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Apr 28, 2025
@D0nte53
Copy link
Author

D0nte53 commented Apr 28, 2025

Thank you for your high-quality responses and your responsiveness. If the second solution is indeed the best, it would force me to repeat t_Prisma everywhere. The solution I found was to use constructor(_prisma: P & t_Prisma<MNs>), but if that's not the correct approach, I will resign myself to replacing all occurrences of P with t_Prisma

@typescript-bot
Copy link
Collaborator

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

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants