Kremdas
Kremdas

Reputation: 140

Typescript - Type to ensure that certain properties exists on an object

I came up with this solution to type-check that function parameters are valid keys of an object.

type SelectOption = {
  value: string;
  label: string;
}

const mapItem = <T extends Record<string, unknown>, K extends keyof T, V extends keyof T>(valueKey: K, labelKey: V) => {
  return (itemToMap: T): SelectOption => ({
    ...itemToMap,
    value: itemToMap[valueKey] as SelectOption['value'],
    label: itemToMap[labelKey] as SelectOption['label'],
  });
};

The reason behind this is that I need to map many arrays of objects across the application to objects with value and label props based on some other props.

One thing I don't like about this is the error message when trying to pass non-existing prop.

e.g.

type CustomObj = {
 name: string;
 id: number;
};

const myObjects: CustomObj[] = [...]

const mapped = myObjects.map(mapItem('id', 'name'));
const mapped2 = myObjects.map(mapItem('id', 'names')); // Argument of type '"names"' is not assignable to parameter of type 'keyof CustomObj'.

My question is if there exists some better solution to this that could perhaps provide a better error message.

Upvotes: 0

Views: 1552

Answers (1)

tenshi
tenshi

Reputation: 26307

I agree with @ij7... this error message seems pretty self-explanatory... but anyways, if you want a custom error message, you could change the signature to something like this:

const mapItem = <T extends Record<string, unknown>, K extends keyof T, V extends string>(valueKey: K, labelKey: V extends keyof T ? V : Error & `'${V}' isn't a valid key bro`) => {

And now you'll get:

Argument of type '"names"' is not assignable to parameter of type 'Error & "'names' isn't a valid key bro"'. Type 'string' is not assignable to type 'Error'.(2345)

🤷 I don't know how helpful that's going to be to you, but hey, at least you can change the error message to your heart's content now!

Upvotes: 2

Related Questions