8

Edited: Change ids type

I have an array with the following values

const ids: number[] = [45, 56];

const obj: any = {
  45: "HELLO",
  56: "WORLD",
};

I would like to type the current any type of my object to restrict it to my ids array values.

I tried with lookup type but I didn't succeed…

Any idea ?

Regards

1
  • 1
    As an aside, the line const ids: string[] = [45, 56]; is in error; 45 and 56 are not strings. Commented Jul 10, 2019 at 10:49

2 Answers 2

14

You can use the Record mapped type. You also need to use a const assertion to capture the literal types of the array elements:

const ids = [45, 56] as const;

const obj: Record<typeof ids[number], string> = {
    45: "HELLO",
    56: "WORLD",
};
const obj2: Record<typeof ids[number], string> = {
    45: "HELLO",
    56: "WORLD",
    57: "WORLD",  // error
};
Sign up to request clarification or add additional context in comments.

2 Comments

Wow! Wonderful, I didn't known that as const existed but it worked, it's used to say that this array is immutable ?
@ScreamZ yes it makes the array readonly, and as a side effect of this tuples and literal types are preserved (you get ids types as [45, 56] instead of number[])
2

If you need to create a function that returns a type-checkable object with keys that correspond to array:

function indexKeys<K extends string>(keys: readonly K[]) {
  type Result = Record<K, number>;

  const result: Result = {} as Result;

  const {length} = keys;

  for (let i = 0; i < length; i++) {
    const k = keys[i];

    result[k] = i;
  }

  return result;
};

Here the type-checker will complain:

// Property 'zz' does not exist on type 'Result'.
const {aa, zz} = indexKeys(['aa', 'bb']); 

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.