7

Let's say I have an array of valid key names

const validKeys = ['a', 'b', 'c']

How can I create an object type that accepts only these keys? This doesn't work:

interface MyObject {
  [key in validKeys]: number // for example
}
4
  • is validKeys array static or dynamically created ? Commented Apr 8, 2019 at 9:56
  • do you need to access the object with an index? e.g myObject['a'] Commented Apr 8, 2019 at 9:58
  • @OnurArı Let's say it's static and I will have to access the object as myObj.a Commented Apr 8, 2019 at 10:01
  • @nachocab Assuming it's static and you don't need to access it with an index, you can just declare interface MyObject { a: number; b: number; c: number } if the keys are optional `interface MyObject { a?: number; b?: number; c?: number } . Commented Apr 8, 2019 at 11:15

2 Answers 2

9

You can use const assertion (added in typescript 3.4) in order to preserve literal types of array items:

const validKeys = ['a', 'b', 'c'] as const;

type Keys = (typeof validKeys)[number]; // "a" | "b" | "c"

type MyObject = { [key in Keys]: number } // { a: number; b: number; c: number; }

Playground

If you use an older typescript version (>=3.0), you can add small utility function which will convert parameters to tuple of literals:

const tuple = <T extends string[]>(...args: T): T => args;
const validKeys = tuple('a', 'b', 'c'); // ["a", "b", "c"]
Sign up to request clarification or add additional context in comments.

Comments

0

if your validKeys are static you can create a type for it. And then from that type, you can set type for object keys. You can do something like:

type ValidKeys = 'a' | 'b' | 'c'
type MyObject = {
    [key in ValidKeys]?: number //You can remove ? if all the keys are mandatory
}

const validKeys: ValidKeys[] = ['a', 'b', 'c']
const obj: MyObject = {
    a: 1,
    b: 1,
    c: 1
}

The keys of object obj can only be one of ValidKeys.

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.