简体   繁体   中英

Define a Typescript type from properties of objects in a list

Say I have a list of objects like:

const TABS = [
  {
        name: 'Home',
        // other properties
  },
  {
        name: 'Profile',
        // other properties
  }
];

How can I define type Tab , which is a type for the 'name' field of each object in the list? Basically the equivalent to

type Tab = 'Home' | 'Profile';

in the case above (but without the need to repeat "Home" and "Profile" in both definitions).

This is possible as long as the value of TABS is known at compile time and you prevent the compiler from widening its type to something like Array<{name: string}> . You want the compiler to remember the specific string literal types of the values you put into the name properties, and not just treat them as string s. The easiest way to do this is to use a const assertion on the TABS array literal at creation time:

const TABS = [
  {
    name: 'Home',
  },
  {
    name: 'Profile',
  }
] as const; // <-- need this 

Now the compiler knows that TABS is a pair of objects and that the first one has a name property of the string literal type "Home" , and that the second one has a name property of the string literal type "Profile" .

At this point you can just use lookup types to get the name property of the elements at the numeric ( number ) indices of the type of TABS :

type Tab = (typeof TABS)[number]["name"];
// type Tab = "Home" | "Profile"

Playground link to code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM