2

I've been working on a previous problem where I think the issue now boils down to the fact that the types are not included in the keyof operator. See the following example:

// my-module.ts
export const someValue = 1
export const anotherValue = 2
export type MyType = "a" | "b" | "c"


// other-file.ts
import * as pkg from "./my-module";

type ValidOptions = {
  [key in keyof typeof pkg]: typeof pkg[key]
}

Using VSCode's IntelliSense shows that ValidOptions only includes the variables, and not MyType.

After discovering this, it seems perfectly reasonable to do so, but I'm wondering if there is a way to include the types as well. I need the types to be able to do something like:

import * as pkg from "@prisma/client";

type Schemas = {
  [K in keyof typeof pkg & pkg.Prisma.ModelName]: typeof pkg[K];
};

Which is a map containing all the available models. I'm trying to do this because Prisma does not export a type like:

type Schemas = User | Log | ...

That lists the models out for me, and I would prefer not having to explicitly define the models myself if possible.


Edit: A more concrete example:

export const someValue = 1
export const anotherValue = 2
export type User = {
  id: number;
  username: string;
  password: string;
};
export type Log = {
  id: number;
  username: string;
  password: string;
};
// Not sure why it is defined like this in the declaration for prisma
export const ModelName: {
  User: "User";
  Log: "Log";
};

export type ModelName = typeof ModelName[keyof typeof ModelName];

Where, using the same other-file.ts as above, the types User and Log are not included in the definition of the ValidOptions type. ValidOptions should only contain User and Log which is why I tried:

type Schemas = {
  [K in keyof typeof pkg & pkg.Prisma.ModelName]: typeof pkg[K];
};
Inkblot
  • 708
  • 2
  • 8
  • 19
  • There's no corresponding value type for those keys; what type should, say, `ValidOptions["a"]` be? Whatever it is, does [this approach](https://tsplay.dev/N7OLqN) meet your needs? If so I could write up an answer; if not, what am I missing? – jcalz May 23 '22 at 12:45
  • Please note that it is unconventional to give a generic type parameter a lowercase name like `key`. The identifier before `in` in a mapped type is a generic type parameter, not the name of a key. So `{[key in keyof typeof pkg]: typeof pkg[key]}` should probably be `{[Key in keyof typeof pkg]: typeof pkg[Key]}` or even more conventionally `{[K in keyof typeof pkg]: typeof pkg[K]}`. – jcalz May 23 '22 at 12:48
  • @jcalz Please see my edit which I hope is a more concrete example. In your suggestion you still include `pkg.MyType` which is what I'm trying to avoid – Inkblot May 23 '22 at 12:55
  • I'm not sure that there is a solution to these kind of module aggregation problems. In a bid to avoid being explicit, is something I research on an almost annual basis but always come away empty handed... – Ian Brindley May 23 '22 at 13:01
  • 2
    Can you be very explicit about what you expect/want `Schemas` to evaluate to? Is it supposed to have a key *named* `User`? If so that's never going to happen automatically because `User` is never included anywhere as a property or string. Type names don't get stringified. – jcalz May 23 '22 at 13:05
  • @jcalz Yes, so `{ User: User, Log: Log }`. But you're saying this is impossible? My initial intuition is that I could use `ModelName` (which is exported by Prisma) to help infer the type names – Inkblot May 23 '22 at 13:08
  • I am indeed saying it's impossible. That `ModelName` type isn't going to help, since its values are just the same strings as the keys. There's no mapping from the name `"User"` to the type named `User`. It would need to export something more useful like `const Models: {User: User; Log: Log}` (note the absence of quotes around the value types), and then you could just use `typeof Models` to be the map you're looking for. As it is I don't know what to tell you to do other than do it manually, especially since I have no prisma expertise (although the question has no prisma tag). – jcalz May 23 '22 at 13:13
  • @jcalz I see. The main issue is just that Prisma does not export that `Models` object which is why I was trying to do all this to define it myself. I suppose doing it manually isn't too much of a hassle anyways – Inkblot May 23 '22 at 13:16
  • So, would you like an answer saying "this is impossible"? – jcalz May 23 '22 at 13:18
  • @jcalz Sure, think it'll be useful for anyone else looking to do something similar. I'll accept it as the answer – Inkblot May 23 '22 at 13:19

0 Answers0