Home > Back-end >  TypeScript fails to get the type of the elements of an object correctly
TypeScript fails to get the type of the elements of an object correctly

Time:12-29

I am developing a React Native project with Expo. I have defined a function called setRoleColors that sets some colors based on the variable role.

export const setRoleColors = (role: string) => {
  switch (role) {
    case "student":
      return { backgroundColor: Color.maroon.dark, color: "#fff" };
    case "moderator":
      return { backgroundColor:"#00ff00", color: "#000"};
    case "user":
      return { backgroundColor:"#0000ff", color: "#fff";
  }
};

I import the function setRoleColors into a component called UserRole.

import React from "react";
import { Text, View } from "react-native";

import { setRoleColors } from "../../services/SetRoleColors";

import styles from "./styles";

const UserRole: React.FC<{ role: string }> = ({ role }) => {
  const { backgroundColor, color } = setRoleColors(role);

  return (
    <View style={{ ...styles.roleContainer, backgroundColor }}>
      <Text style={{ ...styles.roleText, color }}>{role}</Text>
    </View>
  );

Now, everything works perfectly fine, however VS Code underlines the two variables backgroundcolor and color in the line const { backgroundColor, color } = setRoleColors(role); and when I hover over them it shows a message telling me the following:

Property 'backgroundColor' does not exist on type'{backgroundColor: string; color: string} | undefined
Property 'color' does not exist on type'{backgroundColor: string; color: string} | undefined 

CodePudding user response:

Look at your setRoleColors:

export const setRoleColors = (role: string) => {
  switch (role) {
    case "student":
      return { backgroundColor: Color.maroon.dark, color: "#fff" };
    case "moderator":
      return { backgroundColor:"#00ff00", color: "#000"};
    case "user":
      return { backgroundColor:"#0000ff", color: "#fff";
  }
};

If you think about it, it's pretty clear why it might not return an object with a backgroundColor etc property - if role is neither student, nor moderator, nor user. That's what TypeScript is warning you about.

If you want to indicate that those are the only possible roles, you should make a type for those roles, and indicate that type for role instead of a string.

You could also consider using if/else instead of switch.

type Role = 'student' | 'moderator' | 'user';
export const setRoleColors = (role: Role) => {
    if (role === 'student') {
        return { backgroundColor: Color.maroon.dark, color: "#fff" };
    } else if (role === 'moderator') {
        return { backgroundColor:"#00ff00", color: "#000"};
    } else {
        return { backgroundColor:"#0000ff", color: "#fff";
    }
};

You'll also need to change UserRole to indicate that the role should be a Role, and not just a string.

  • Related