Home > Mobile >  Infer property type from object list type
Infer property type from object list type

Time:08-04

I have a TypeScript type Items, and it is used for an object list like this:

const items: Items = {
 '1': { id: '1', name: 'first' },
 '2': { id: '2', name: 'second' },
}

I want to derive the type Item from Items, so that this is valid:

const getItem = (items: Items, key: string): Item => {
  return items[key];
}

How can I derive Item from Items?

CodePudding user response:

I don't exactly know how the type Items is defined so I used typeof items:

type Item = typeof items[keyof typeof items];

CodePudding user response:

I'd do the opposite: derivate Items from Item to proceed from simple to complex. This is IMHO a cleaner way to design things.

interface Item {
    id: string;
    key: string;
}
type Items = {[key : string] : Item};

Anyway, if you can't change the way you define them, you can try to implement a valueof that would be a keyof analogous.

type ValueOf<T> = T[keyof T];

Then you would just use it this way:

type Item =  ValueOf<Items>;

(See a post here)

But if you define Items this way or something similar (you didn't mention it in your question)...

type Items = {
    '1': {
        id: string;
        name: string;
    };
    '2': {
        id: string;
        name: string;
    };
}

...You get Item the could be redefined as

type Item = {
    id: string;
    name: string;
} | {
    id: string;
    name: string;
}

...which is a bit dumb IMHO.

CodePudding user response:

  type Item = { id: string; name: string };
  type Items = Record<string, Item>;
  const items: Items = {
    '1': { id: '1', name: 'first' },
    '2': { id: '2', name: 'second' },
  };
  type IKey = keyof typeof items;

  const getItem = (items: Items, key: IKey): Item => {
    return items[key];
  };

OR

Following the template of items object

  type IKey = keyof typeof items;
  type Item = typeof items[IKey];

  const getItem = (items: Items, key: IKey): Item => {
    return items[key];
  };
  • Related