Currently, I am working on developing a React component that wraps around the Select component from react-select. The issue arises with a specific prop declaration that can be seen here:
export type SelectComponentsProps = { [key in string]: any };
export interface Props<OptionType extends OptionTypeBase = { label: string; value: string }> extends SelectComponentsProps {
I have imported this type and then attempted to declare the props of my wrapper component like so:
import { Props as SelectProps } from "react-select/src/Select";
type Props = Omit<SelectProps, "inputId"> & { ... some other stuff };
The problem I encountered was that I could pass anything I wanted to my component without any type checking, even for fields that had explicit type declarations on SelectProps
:
// acceptable
<MySelectWrapper onChange="definitely not a function"/>
// not acceptable, does not pass type checking
<Select onChange="definitely not a function"/>
Upon further investigation, I discovered that the use of Omit
along with an index signature (as seen in the react-select example: SelectComponentsProps
) led the compiler to ignore explicitly-specified fields and rely solely on the index signature.
interface ArbitraryKeyable {
foo: number;
[key: string]: any;
}
const value = {
foo: 'not a number',
bar: 'this can be anything'
}
// Fails: foo is the wrong type.
const arbitrary: ArbitraryKeyable = value;
type OmittedArbitraryKeyable = Omit<ArbitraryKeyable, 'this is not a field'>;
// Succeeds, even though the type should functionally be the same.
const omittedArbitrary: OmittedArbitraryKeyable = value;
This is how the playground interprets that type:
https://i.sstatic.net/jBGJ1.png
It accepts everything due to this interpretation! Is there a way to define an alternative form of Omit
that keeps the explicitly-defined fields? Or perhaps, is there a type manipulation that can eliminate the index signature and only retain the explicit fields? (While it may not be necessary for my current scenario, sacrificing flexibility for increased type safety elsewhere might be preferable).