In my code, there is a type called Component
with a generic parameter named Props
, which must adhere to the Record<string, any>
structure. I am looking to create a type that can accept a component in one property and also include a function that returns the Props
for that component. These objects will then be stored in a dictionary format like so:
const components: Record<string, ComponentConfig> = {
someKey: {
component: Component1, // Implements the Component<{num: number}> type,
props() { // Strongly typed Props
return {
num: 1
}
}
},
someOtherKey: {
component: Component2, // Implements the Component<{str: string}> type,
props() { // Strongly typed Props
return {
str: "test"
}
}
}
}
I attempted a solution using this approach:
type ComponentConfig = never extends infer Props
? Props extends Record<string, any>
? {
component: Component<Props>
props(): Props
}
: string // originally never, modified for this example
: never
However, I encountered an error when assigning an object to a key within the dictionary:
// TS2322: Type { component: Component<{ num: number; }>; props(): { num: number; }; } is not assignable to type never
const cfg: Record<string, ComponentConfig> = {
someKey: {
component: component1,
props() {
return {
num: 1
}
}
}
}
I am puzzled by this error as 'never' seems to extend everything. The logic dictates that the first ternary expression should always evaluate to true because the empty set is a subset of every set. Thus, depending on the type of Props
, the resolved type should either be
{component: Component<Props>; props(): Props}
or string
. However, I consistently receive 'never', which confuses me.
I am using these methods to introduce a new type variable Props
. If there are more elegant solutions to achieve this, I am open to suggestions.
Initially, I thought about passing it as a generic argument, but that would not work since I would need to specify it while creating the cfg
Record. Using any/unknown as a placeholder would lead to incorrect typings for the props function. Essentially, my goal is to infer the generic argument of the component
property and utilize it as the return type for the props
function.