Reputation: 926
I'm trying to loop over an array of functions (doing network calls) that return different types of configuration objects. Based on this configuration I'm rendering react components with different props. But I'm struggling to get typescript to co-operate in this.
Here's a simplified example of what I had so far;
type FirstConfig = {
a: 'a';
};
type SecondConfig = {
b: 'b';
};
type ConfigObject = FirstConfig | SecondConfig;
type ConfigFunction = () => ConfigObject;
const configArray: ConfigFunction[] = [() => ({ a: 'a' }), () => ({ b: 'b' })];
configArray.map(getConfig => {
const { a, b } = getConfig();
console.log(a, b);
});
Whenever I loop over the array of config functions and call it, It seems to complain that none of the properties defined on the ConfigObject
are present. Any tips/guidance here?
Upvotes: 2
Views: 693
Reputation: 246
This is expected behavior.
Your ConfigObject
is either FirstConfig
or SecondConfig
. Before accessing their distinct properties you must resolve their type or if the property exists in that type.
There are different ways you can achieve this.
const isFirstConfig = (config: ConfigObject): config is FirstConfig => !!(config as any).a;
const config = getConfig();
if ("a" in config) {
// the config is of FirstConfig type here
}
type FirstConfig = {
type: "first";
a: "a";
};
type SecondConfig = {
type: "second";
b: "b";
};
then you can check types like this
const config = getConfig();
if (config.type === "first") {
console.log("first type");
// config is FirstConfig type in this 'if' block
}
type ConfigObject = {
a?: "a";
b?: "b";
};
In this case you can write your initial code:
const { a, b } = getConfig();
console.log({ a, b });
Upvotes: 3