Reputation: 863
Consider the below code, the code const foundKey = classDict[key]
should have the type object | undefined
, because it's possible to enter in a key that's not part of the dict
object (e.g. dict['bar']
).
However, I can't seem to figure out how to accomplish this. Does anybody how to accomplish this?
function classMatcher<
K extends keyof T,
T extends baseClassDict_T
>(keys: K[], classDict: T): T[K] | undefined {
for (let key of keys) {
const foundKey = classDict[key]; // <---- Type = object, should equal object | undefined
if (foundKey !== undefined) return foundKey;
}
return undefined;
}
type baseClassDict_T = {
[key: string]: {
component: (prop: any) => JSX.Element;
};
};
const keys = ['foo', 'bar'];
const dict = {
foo: {
component: //misc...
}
}
classMatcher(keys, dict)
Upvotes: 0
Views: 133
Reputation: 7080
I think you've missed the point here. If everything is typed properly, there would be no possibility that it will evaluate to undefined
. Let me explain.
From this type:
type baseClassDict_T = {
[key: string]: {
component: (props: any) => JSX.Element;
}
}
All key
of an object of this type will always be a string.
Next, the important part:
function classMatcher<K extends keyof T, T extends baseClassDict_T>(keys: K[], classDict: T)
The generic K extends keyof T
basically says that K will always be a string, and this string will always be one of the properties from T.
What this means is that the argument keys
can never accept any strings that is not a property of argument classDIct
. Meaning this code:
classMatcher(['a', 'b', 'c'], {
a: { component: <></> },
c: { component: <></> }
});
Will always have a typing error and never get past type checking because the key "b" is not present in classDict object.
Therefore, the line:
const foundKey = classDict[key];
Will never evaluate to undefined.
See this playground for the explanation in action.
Upvotes: 1