0

Is it possible to use a variable to get the typeof a key in a interface?

For example:

interface DbSchema {
  jobs: {
    jobId: number;
    jobName: string;
  }
  users: {
    userId: number;
    userName: string;
  }
}

// I know we can do this:
type JobsType = DbSchema["jobs"];

// Is there a way to do this:
const str = "jobs";
type JobsType = DbSchema[str];
Pieter
  • 38
  • 9
  • I don’t think so since interfaces exist only at compile-time, but I’d love for someone with more TypeScript experience to chime in. Having said that, I smell an XY problem. What are you actually trying to accomplish? – Julia Dec 17 '22 at 12:47
  • Of course, didn't think of compile-time. I think I overthinked it. I am trying to accomplish a interface for a whole database schema and later in my code get a subscheme of a table. But I think I have to take another approach :) Thnx. – Pieter Dec 17 '22 at 12:54
  • It's not possible because of [Type Erasure](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types). From your comment static typing is not what you are looking for. Instead look into an [ORM](https://stackoverflow.com/questions/1279613/what-is-an-orm-how-does-it-work-and-how-should-i-use-one) solution. – Inigo Dec 17 '22 at 15:28

2 Answers2

1
interface DbSchema {
  jobs: {
    jobId: number;
    jobName: string;
  }
  users: {
    userId: number;
    userName: string;
  }
}

const str = "jobs";
type JobsType = DbSchema[typeof str];

![enter image description here

playground

const already narrow the type for you, you just need typeof

Acid Coder
  • 2,047
  • 15
  • 21
0

You can do it, using keyof and typeof keywords like this:

const s:keyof DbSchema = "jobs"
type JobsType = DbSchema[typeof s];

You should guarantee that type of s is keyof DbSchema and also when you want to get the type of one of the DbSchema properties you have to use typeof s.


But I think the more reasonable and cleaner approach is using a generic type. You can define a type like this :

type DbSchemaPropertyType<T extends keyof DbSchema> = DbSchema[T];

And use it easily :

const job:DbSchemaPropertyType<"jobs"> = {
    jobId: 1,
    jobName: "student"
}
mahooresorkh
  • 1,361
  • 2
  • 8
  • 16
  • You don't want to use `const str: keyof DbSchema = "jobs"`. This will broaden the type of `str` from `"jobs"` to the union `"jobs" | "users"`. You get stronger typing without it. With `const str = "jobs"` the type of `str` is the literal string `"jobs"`, as it is a `const` and cannot be re-assigned. – Linda Paiste Dec 17 '22 at 20:51
  • You are right, it is possible to use `const str = "jobs"`. By means of inference the type of `str` will be `"jobs"`. But also when we do it like this `const str: keyof DbSchema = "jobs"` and after that, define another const like this : `const n = s;` , `n` type will be infered as `"job"` not `"jobs" | "users"`. – mahooresorkh Dec 18 '22 at 05:54