skip to Main Content

Have been given a typed object

type TestObj = {
    one: "up";
    two: "down";
    three: "left";
    four: "right";
}

Of which I have to choose 0 or more keys from and turn into an array

type TestObjKeys = keyof TestObj;
const chosen: TestObjKeys[] = ["one", "four"];

I need to convert this into a new typescript obj for only the keys that were chosen

type NewTestObj = Pick<TestObj, (typeof chosen)[number]>;

However the above gives me a type (equivalent to TestObj) for all keys, rather than use "one" and "four". I tried turning it into a const

const chosen2 = chosen as const;

But it errors out with

A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.(1355)

How can I get only the chosen keys?

Sandbox

2

Answers


  1. (typeof chosen)[number] is just TestObjKeys not chosen keys.

    If you add as const assertion to chosen directly, without the explicit type it would work.

    const chosen = ["one", "four"] as const;
    

    If you still need explicit type i recommend using the satisfies operator.

    const chosen = ["one", "four"] as const satisfies TestObjKeys[];
    
    Login or Signup to reply.
  2. You need to:

    1. Not put a type on chosen, so TypeScript can infer it. (You could use satisfies to make sure it satisfies a type, though, if you wanted.)

      and
    2. Use as const on the array you’re assigning to chosen, so TypeScript knows it’s a tuple of string literal types, not an array of string.

    Like this:

    const chosen = ["one", "four"] as const;
    type NewTestObj = Pick<TestObj, (typeof chosen)[number]>;
    

    Playground link

    (There’s also no need for the () around typeof chosen, it has higher precedence [if that’s the word] than the [number] after it. Just typeof chosen[number] will do the job.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search