Material-UI v5 uses Emotion for the default style engine and consistently uses styled internally in order to make it easier for people who want to use styled-components instead of Emotion to not have to include both in the bundle.
Though the styled API works fine for a lot of use cases, it seems like a clumsy fit for this particular use case. There are two main options that provide a considerably better DX.
One option is to use the new sx prop available on all Material-UI components (and the Box component can be used to wrap non-MUI components to access the sx features). Below is a modification of one of the List demos demonstrating this approach (with the custom ListItemButton simulating the role of your ListItemLink):
import * as React from "react";
import Box from "@material-ui/core/Box";
import List from "@material-ui/core/List";
import MuiListItemButton, {
ListItemButtonProps
} from "@material-ui/core/ListItemButton";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Divider from "@material-ui/core/Divider";
import InboxIcon from "@material-ui/icons/Inbox";
import DraftsIcon from "@material-ui/icons/Drafts";
const ListItemButton = ({
selected = false,
...other
}: ListItemButtonProps) => {
const match = selected;
return (
<MuiListItemButton
{...other}
sx={{ color: match ? "primary.main" : undefined }}
/>
);
};
export default function SelectedListItem() {
const [selectedIndex, setSelectedIndex] = React.useState(1);
const handleListItemClick = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
index: number
) => {
setSelectedIndex(index);
};
return (
<Box sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}>
<List component="nav" aria-label="main mailbox folders">
<ListItemButton
selected={selectedIndex === 0}
onClick={(event) => handleListItemClick(event, 0)}
>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItemButton>
<ListItemButton
selected={selectedIndex === 1}
onClick={(event) => handleListItemClick(event, 1)}
>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Drafts" />
</ListItemButton>
</List>
<Divider />
<List component="nav" aria-label="secondary mailbox folder">
<ListItemButton
selected={selectedIndex === 2}
onClick={(event) => handleListItemClick(event, 2)}
>
<ListItemText primary="Trash" />
</ListItemButton>
<ListItemButton
selected={selectedIndex === 3}
onClick={(event) => handleListItemClick(event, 3)}
>
<ListItemText primary="Spam" />
</ListItemButton>
</List>
</Box>
);
}

The only downside of this approach is that it is currently notably slower than using styled, but it is still fast enough to be fine for most use cases.
The other option is to use Emotion directly via its css prop. This allows a similar DX (though not quite as convenient use of the theme), but without any performance penalty.
/** @jsxImportSource @emotion/react */
import * as React from "react";
import Box from "@material-ui/core/Box";
import List from "@material-ui/core/List";
import MuiListItemButton, {
ListItemButtonProps
} from "@material-ui/core/ListItemButton";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Divider from "@material-ui/core/Divider";
import InboxIcon from "@material-ui/icons/Inbox";
import DraftsIcon from "@material-ui/icons/Drafts";
import { css } from "@emotion/react";
import { useTheme } from "@material-ui/core/styles";
const ListItemButton = ({
selected = false,
...other
}: ListItemButtonProps) => {
const match = selected;
const theme = useTheme();
return (
<MuiListItemButton
{...other}
css={css({ color: match ? theme.palette.primary.main : undefined })}
/>
);
};
export default function SelectedListItem() {
const [selectedIndex, setSelectedIndex] = React.useState(1);
const handleListItemClick = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
index: number
) => {
setSelectedIndex(index);
};
return (
<Box sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}>
<List component="nav" aria-label="main mailbox folders">
<ListItemButton
selected={selectedIndex === 0}
onClick={(event) => handleListItemClick(event, 0)}
>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItemButton>
<ListItemButton
selected={selectedIndex === 1}
onClick={(event) => handleListItemClick(event, 1)}
>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Drafts" />
</ListItemButton>
</List>
<Divider />
<List component="nav" aria-label="secondary mailbox folder">
<ListItemButton
selected={selectedIndex === 2}
onClick={(event) => handleListItemClick(event, 2)}
>
<ListItemText primary="Trash" />
</ListItemButton>
<ListItemButton
selected={selectedIndex === 3}
onClick={(event) => handleListItemClick(event, 3)}
>
<ListItemText primary="Spam" />
</ListItemButton>
</List>
</Box>
);
}

In the app I work on (which I haven't yet started to migrate to v5), I expect to use a combination of styled and Emotion's css function/prop. I'm hesitant to use the sx prop heavily until its performance improves a bit (which I think will happen eventually). Even though it performs "fast enough" for many cases, when I have two options with similar DX available and one is twice as fast as the other, I find it difficult to opt for the slower one. The main cases where I would opt for the sx prop are for components where I want to set CSS properties differently for different breakpoints or similar areas where the sx prop provides much nicer DX than other options.
Related answers: