I'm trying to type an interface/object correctly so that I can make functions for each object with a certain type. I don't know how to try and explain it better so I will give you some code.
This is my interface:
export interface Activity {
id: string;
metaData:
| {
type: "createTask";
data: { taskId: string; taskName: string; user: string };
task: string;
taskName: string;
}
| {
type: "deleteTask";
data: { taskName: string; user: string };
task: string;
taskName: string;
}
| {
type: "updateTask";
data: { taskId: string; taskName: string; user: string };
task: string;
taskName: string;
}
| {
type: "createScenario";
data: {
scenarioId: string;
scenarioName: string;
taskName: string;
user: string;
};
task: string;
taskName: string;
}
| {
type: "updateScenario";
data: { scenarioId: string; scenarioName: string; user: string };
task: string;
scenario: string;
taskName: string;
}
| {
type: "deleteScenario";
data: { scenarioName: string; user: string };
task: string;
taskName: string;
};
}
And now from this interface I want to type a function for each different type of activity so that I can lookup that function based on the type.
This is what I tried:
export const activityFormatFunctions: Record<
Activity["metaData"]["type"],
(activity: Activity) => string
> = {
createScenario: (activity) => {
return ""
},
createTask: (activity) => {
return ""
},
deleteScenario: (activity) => {
return ""
},
deleteTask: (activity) => {
return ""
},
updateScenario: (activity) => {
activity.metaData.data.scenarioName;
return ""
},
updateTask: (activity) => {
activity.metaData.data.taskName;
return ""
},
};
The problem is that the "activity" parameter is not narrowed to the activity with the matching type making it so I can only access common properties between all of the different activity types.
In my example above I want to be able to access scenarioName in the updateScenario scenario function because the Activity interface says it has a scenarioName
{
type: "updateScenario";
data: { scenarioId: string; scenarioName: string; user: string };
task: string;
scenario: string;
taskName: string;
}