Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

82
Visualizações
Handling of optional properties of objects to be used as mapped or indexed properties

I am working on a scenario of handling an array type property with indexed access. Tried to encapsulate the problem in simplest form here.

type User = {
    readonly name: string; 
    readonly roles: ReadonlyArray<string>;
}

const buildActions = <T extends User>(u: T) => {
    // Implementation
    return {login: (role: T['roles'][number]) => {
        console.log(u, role);
    }}
}

const actions = buildActions({name: 'user', roles: ['admin', 'client']} as const);
actions.login('client');

So above code works fine. But in my scenario the property roles is optional.

type User = {
    readonly name: string; 
    readonly roles?: ReadonlyArray<string>;
}

In above case we get error

Type 'number' cannot be used to index type 'T["roles"]'

I tried to use conditional type to handle the scenario but didn't worked out.

const buildActions = <T extends User>(u: T) => {
    // Implementation
    return {login: (role: T['roles'] extends never ? never : T['roles'][number]) => {
        console.log(u, role);
    }}
}

Definitely it's not the right way to handle such scenario, but covers the use case very well.

Any idea how to get through this typing scenario?

Thanks

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Using the conditional types solved the problem.

type User = {
    readonly name: string; 
    readonly roles?: ReadonlyArray<string>;
}

const buildActions = <T extends User>(u: T) => {
    // Implementation
    return {login: (role: T['roles'] extends string[] ? T['roles'][number] : never) => {
        console.log(u, role);
    }}
}

const actions = buildActions({name: 'user', roles: ['admin', 'client']} as const);
actions.login('client');

Tried that earlier but seems there is a precedence issues with TS extends keyword. Considering that T['roles'] as type string[] | undefined The following code below works fine:

T['roles'] extends string[] ? T['roles'][number] : never

But if we reverse the condition it fails.

T['roles'] extends undefined ? never : T['roles'][number] 

So never use conditional types with undefined assertion.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda