The HTMLProps<HTMLInputElement> generic type is including types that can't be assigned to a styled-component. If it were a plain HTML input element, then those types would be valid. Instead, I'd recommend type casting your MySlider props.
Working demo:

App.tsx
import * as React from "react";
import MySlider from "./MySlider";
import "./styles.css";
export default function App() {
const [value, setValue] = React.useState("10");
function onChange(e: React.ChangeEvent<HTMLInputElement>): void {
setValue(e.target.value);
}
return (
<div className="App">
<MySlider value={value} onChange={onChange} step="10" />
</div>
);
}
MySlider.tsx
import * as React from "react";
import styled from "styled-components";
const MyRange = styled.input.attrs({ type: "range" })`
appearance: none;
background: gray;
width: 100%;
height: 40px;
outline: none;
box-sizing: border-box;
margin: 0;
::-webkit-slider-thumb {
appearance: none;
height: 40px;
width: 40px;
background: red;
cursor: pointer;
}
`;
export type MySliderProps = {
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
value: string;
step: string;
};
export const MySlider = (props: MySliderProps): React.ReactElement => (
<>
<MyRange {...props} />
<span>{props.value}</span>
</>
);
export default MySlider;
Be careful about mixing numbers and strings. While you initially set your value state as a number, it's being set a string in the onChange callback. For example, event.target.value is a string (numbers are stored as strings within the DOM). Either keep it as a string or utilize parseInt to retain value as a number:
function onChange(e: React.ChangeEvent<HTMLInputElement>): void {
setValue(parseInt(e.target.value, 10));
}
On a separate note, there's a push to deprecate the usage of FC.