2

I have a list

export const list = [
  {
    name: 'parentTitle',
  },
  {
    name: 'anotherTitle',
  },
  {
    name: 'whatever',
  },
];

Now I want to create dynamically a union type which describes the following:

type Title = 'parentTitle' | 'anotherTitle' | 'whatever';

Is there a way to do this?

I tried to adapt the idea here: Keyof nested child objects But I can't figuring it out

3 Answers 3

6

The type of list in your example gets inferred by the compiler to be Array<{name: string}>, and thus the compiler has completely forgotten the particular string literal types of the name properties by the time you try to define Title.

You'll have to change how you assign list, at least somewhat. The easiest thing to do (which may or may not meet your needs) is to use a const assertion, which asks the compiler to infer the narrowest type possible:

export const list = [
    { name: 'parentTitle', },
    { name: 'anotherTitle', },
    { name: 'whatever', },
] as const;

Now list is inferred to be of type:

/* 
const list: readonly [
    { readonly name: "parentTitle";}, 
    { readonly name: "anotherTitle";}, 
    { readonly name: "whatever";}
]
*/

which is a readonly tuple of readonly objects with particular name properties in a particular order. From that we can use lookup types to define Title:

type Title = typeof list[number]["name"];
// type Title = "parentTitle" | "anotherTitle" | "whatever"

Okay, hope that helps; good luck!

Playground link to code

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! Great answer! But I think I have another case. I'm importing the list from a .json File and not directly in typescript. But I can't define the list of the json File with as const as you suggested. Is there a way to do this with a list from a json file? import list from './list.json'; type Title = typeof list[number]['name'];
Please edit the question code to be a minimal reproducible example if importing JSON is a requirement; I'm afraid that options for importing JSON are limited. There is a request to be able to import a json file as const, but it's not implemented yet.
1

You can do as this:

type GetNameFromList<T extends readonly {name: string}[]> = T[number]['name'];
const list = [
  {
    name: 'parentTitle',
  },
  {
    name: 'anotherTitle',
  },
  {
    name: 'whatever',
  },
] as const;

//here is what you want
type values = GetNameFromList<typeof list>;  // 'parentTitle' | 'anotherTitle' | 'whatever'

Comments

0

You can make an interface for it and make an array type from it.

interface Title {
    name: 'parentTitle' | 'anotherTitle' | 'whatever';
}

let list: Title[] = [
  {
    name: 'parentTitle',
  },
  {
    name: 'anotherTitle',
  },
  {
    name: 'whatever',
  },
];

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.