I have the following type which represents an item store:
export type ItemStore<T> = {
allById: {
[id: string]: T,
},
activeById: {
[id: string]: T,
},
all: T[],
active: T[],
fetching: boolean,
cursor: string,
}
And I have a component that utilizes an item store, but is written such that the store type is generic and it should infer the item type from the store type. I need labelKey and valueKey to accept the keys of the item type.
type Props<S, I = S extends ItemStore<infer IT> ? IT : never> = {
store: S,
labelKey: keyof I,
valueKey: keyof I,
}
function StoreItemList<S>(props: Props<S>): JSX.Element {
...
}
Example usage of this might be:
type UserItem = {
id: number,
name: string,
}
const userStore: UserStore<UserItem> = { ... }
<StoreItemList
store={userStore}
labelKey="id" // This should only accept 'id' and 'name' (keys of UserItem)
valueKey="name" // This should only accept 'id' and 'name' (keys of UserItem)
/>
However, this doesn't work. In the above example, it's evaluating store as unknown. Where am I going wrong?
Edit: Turns out this was ultimately an issue with the styled-components package I'm using. For some reason wrapping the component styled(StoreItemList) messes up the types. Once I removed the styled wrapper, the types worked as expected...
Edit 2: Looks like this is a known issue with styled-components when using generic components: https://github.com/styled-components/styled-components/issues/1803