0

I have a long array:

const allRoles = {
   'product_manager': [
      {
         id: 'productManager_1',
         image: '/icon.png',
         title: 'CEO of the product',
         description: 'Some description'.</>,
      },
   'backend_engineer': [{...}]
   ...
}

Component code:

// roleTitle = "Product Manager"
export function OverviewModal(roleTitle: string) {

  const convertedRole: keyof typeof allRoles = roleTitle.toLowerCase().replace(/ /g,'_');
  const roleCardInfo = allRoles[convertedRole];
  // Tried the above but got an error:
  // Type 'string' is not assignable to type '"product_manager" | "backend_engineer"...'.ts(2322)

In this case, this doesn't seem to apply: Typescript Type 'string' is not assignable to type

Instead of a class, I just have an object of arrays. I'm not sure what type it would be in this scenario.

Lewis
  • 135
  • 1
  • 10

2 Answers2

1

So at this part you are literally saying that convertedRole should be some key of allRoles.

const convertedRole: keyof typeof allRoles

the type of allRoles is the shape of the value you are giving it. And you have declared your argument roleTitle as a string. So a string is not narrow enough a type for convertedRole. convertedRole can only be assigned strings that are equal to the keys of the type of allRoles, aka the strings "product_manager" | "backend_engineer"...'.

Remember that typescript does not exist in runtime. It can not know the actual value of roleTitle as you run the code.

cengen
  • 61
  • 1
  • 3
1

Cengen is right.

But, may you would have a solution to your problem if you were able to know at compile time the key of AllRoles like this :

const roleTypeNames = ['product_manager','backend_engineer'] as const;
type roleType = typeof roleTypeNames[number]

const allRoles : {[key in roleType]:any} = { ... };

if yes, then you can use a typeguard.

const isRoleType = (candidate : string) : candidate is roleType => {
    for(const role of roleTypeNames)
    {
        if(role === candidate) return true  ;
    }
    return false;
}

 function OverviewModal(roleTitle: string) {
    const sanitizedRoleTitle = roleTitle.toLowerCase().replace(/ /g,'_');
    if(isRoleType(sanitizedRoleTitle))
    {  
        const roleCardInfo = allRoles[sanitizedRoleTitle];
    }
  }
Romain TAILLANDIER
  • 1,765
  • 10
  • 18