Typescript - How to return dynamic "object key" that comes from dynamic "prop key value"?

Viewed 963

I'm trying to generate "dynamic object key" based of "prop key value" by picking specific object key value.

So let's say I pass in { name: 'someEntity', unrelatedKey: 123 } and I would like to return { someEntity: 'ok' }. How would one do that so the return value is typescript type defined? I've tried something like this but it does not work:

type GetExampleProps = {
  name: string
  unrelatedKey: number
}

type GetExampleRes<T> = {
  [key: T]: string
}

function getExample<T extends GetExampleProps> (props: T): GetExampleRes<T['name']> {
  return {
    [props.name]: 'ok'
  }
}

const example = getExample({ name: 'someEntity', unrelatedKey: 123 })

example.someEntity  // should be valid type string
example.hello       // should be invalid, missing key
2 Answers

Currently I am unable to do that without a type assertion, but as a temporary solution here it is:

type GetExampleProps<T extends PropertyKey = string> = {
  name: T;
  unrelatedKey: number;
};

function getExample<T extends PropertyKey>(
  props: GetExampleProps<T>
): {
  [K in T]: string;
} {
  const toRet = {
    [props.name]: "a string",
  };

  return toRet as { [K in T]: string };
}

const example = getExample({ name: "someEntity", unrelatedKey: 123 });

example.someEntity;
example.hello; // Property 'hello' does not exist on type '{ someEntity: string; }'

Try this function, this should work the way you need

const createObject = (obj: any) => {
    interface I {
        [name: string]: any;
    }
    const returnObj: I = {};
    returnObj[obj.name] = Object.keys(obj).filter((key) => key !== "name");
    return returnObj;
};
Related