0

I have a set of storage properties:

interface StoredProps {
  location: boolean;
  notification: boolean;
}

I also get the strings representing the stored properties using keyof:

type StorableKeys = keyof StoredProps;

I have a function that can retrieve multiple stored properties at once:

const = getStoredProps<T extends StorableKeys[]>(keys: T) =>
  keys.map(key => storage.get(key)).reduce((props, value, idx) => {
    props[keys[idx]] = value;
    return props;
  }, {});

This works, however the return type is ultimately {}. I want the return type to match an object created by the keys.

I've tried using {} as { [M in keyof T]: T[M] }, but this doesn't work because T is an array type so this just ends up giving me an array type. I've also tried [M in T], but this is a syntax error.

Is there any way to derive a type from an array of property names?

1 Answer 1

2

Maybe something like this?

const getStoredProps = <K extends StorableKeys>(keys: K[]) =>
  keys.map(key => storage.get(key)).reduce((props, value, idx) => {
    props[keys[idx]] = value;
    return props;
  }, {} as Pick<StoredProps, K>);
}

The idea is to make the generic type just a union of keys K instead of an array of them, which is more straightforward. And then keys is of type K[]. The real value is the return type, Pick<StoredProps, K>, which is defined like {[P in K]: StoredProps[P]}, and it works now because K is a key type not an array type.

You might have been able to get away with T extends StorableKeys[] and then Pick<StoredProps, T[number]>, but I don't think you really mean to say that T could be a subtype of Array.

Hope that helps. Good luck.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.