Home > front end >  String literals from array of object
String literals from array of object

Time:10-17

I have the next code:

interface IPeople {
 id: number,
 role: string
}

const peoples: IPeople[] = [
 {
  id: 1,
  role: 'student'
 },
 {
  id: 2,
  role: 'teacher'
 }
]

I need to get the type of string literals based on peoples roles:

type PeoplesRoles = 'student' | 'teacher'

Can i do it dinamically? Thanks

CodePudding user response:

You need to make peoples array immutable so TS is able to infer all keys and values.

interface IPeople {
  id: number,
  role: string
}

const peoples = [
  {
    id: 1,
    role: 'student'
  },
  {
    id: 2,
    role: 'teacher'
  }
] as const;

type Peoples = typeof peoples;

//  "student" | "teacher"
type PeoplesRole = Peoples[number]['role']

Playground

UPDATE

If role is optional ...

interface IPeople {
  id: number,
  role: string
}

const peoples = [
  {
    id: 1,
    role: 'student'
  },
  {
    id: 2,
  }
] as const;

type Peoples = typeof peoples;

type ObtainRole<T> =
  (T extends any
    ? (T extends { role: infer Role }
      ? Role
      : never
    )
    : never
  )
  
// "student"
type PeoplesRole = ObtainRole<Peoples[number]>

Why i have used T extends any ? - To distribute the union type. See docs

After union distribution, this line T extends { role: infer Role } applies to every element.

  • Related