Overview
The exercise types define the structure for exercise data, including individual exercises and paginated responses. These types ensure type safety when working with exercise data throughout your application.
IExercise
Represents a single exercise with all its properties.
interface IExercise {
name: string;
title: string;
target: string;
muscles_worked: string;
bodyPart: string;
equipment: string;
id: string;
id_: string;
blog: string;
images: string[];
gifUrl: string;
videos: string[];
keywords: string[];
}
Properties
Unique identifier name for the exercise (usually lowercase with hyphens)
Display title of the exercise for user interfaces
Primary target muscle or muscle group
Comma-separated list of all muscles engaged during the exercise
Body part category (e.g., “chest”, “back”, “legs”)
Required equipment for the exercise (e.g., “barbell”, “bodyweight”)
Primary identifier for the exercise
Alternative identifier for the exercise
URL or path to related blog content or detailed instructions
Array of image URLs showing exercise form and technique
Animated GIF URL demonstrating the exercise movement
Array of video URLs with exercise tutorials and demonstrations
Search keywords and tags for exercise discovery
IExerciseData
Paginated response containing multiple exercises.
interface IExerciseData {
totalExercises: number;
totalPages: number;
data: IExercise[];
}
Properties
Total count of exercises matching the query
Total number of pages available for pagination
Array of exercise objects for the current page
IExerciseResponse
Wrapper for a single exercise response.
interface IExerciseResponse {
data: IExercise;
}
Properties
Usage Examples
Fetching Exercises
Single Exercise
Filtering by Type
React Component
import { IExerciseData } from './types';
async function getExercises(
page: number = 1,
limit: number = 10
): Promise<IExerciseData> {
const response = await fetch(
`https://api.bodyworks.io/exercises?page=${page}&limit=${limit}`
);
return response.json();
}
// Type-safe usage
const exercises = await getExercises(1, 20);
console.log(`Total: ${exercises.totalExercises}`);
console.log(`Pages: ${exercises.totalPages}`);
exercises.data.forEach((exercise: IExercise) => {
console.log(`${exercise.title} - ${exercise.target}`);
});
import { IExerciseResponse, IExercise } from './types';
async function getExerciseById(id: string): Promise<IExercise> {
const response = await fetch(
`https://api.bodyworks.io/exercises/${id}`
);
const result: IExerciseResponse = await response.json();
return result.data;
}
// Type-safe usage
const exercise = await getExerciseById('bench-press');
console.log(exercise.title);
console.log(exercise.target);
console.log(exercise.equipment);
console.log(exercise.gifUrl);
import { IExerciseData, IExercise } from './types';
function filterByBodyPart(
exerciseData: IExerciseData,
bodyPart: string
): IExercise[] {
return exerciseData.data.filter(
(exercise) => exercise.bodyPart.toLowerCase() === bodyPart.toLowerCase()
);
}
function filterByEquipment(
exerciseData: IExerciseData,
equipment: string
): IExercise[] {
return exerciseData.data.filter(
(exercise) => exercise.equipment.toLowerCase() === equipment.toLowerCase()
);
}
// Usage
const allExercises = await getExercises();
const chestExercises = filterByBodyPart(allExercises, 'chest');
const barbellExercises = filterByEquipment(allExercises, 'barbell');
import React, { useState, useEffect } from 'react';
import { IExercise, IExerciseData } from './types';
interface ExerciseListProps {
bodyPart?: string;
}
export const ExerciseList: React.FC<ExerciseListProps> = ({ bodyPart }) => {
const [exercises, setExercises] = useState<IExercise[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchExercises() {
const response = await fetch(
`https://api.bodyworks.io/exercises${bodyPart ? `?bodyPart=${bodyPart}` : ''}`
);
const data: IExerciseData = await response.json();
setExercises(data.data);
setLoading(false);
}
fetchExercises();
}, [bodyPart]);
if (loading) return <div>Loading...</div>;
return (
<div>
{exercises.map((exercise) => (
<div key={exercise.id}>
<h3>{exercise.title}</h3>
<img src={exercise.gifUrl} alt={exercise.title} />
<p>Target: {exercise.target}</p>
<p>Equipment: {exercise.equipment}</p>
</div>
))}
</div>
);
};
Type Guards
Create type guards to safely validate exercise data:
function isValidExercise(obj: any): obj is IExercise {
return (
typeof obj === 'object' &&
typeof obj.name === 'string' &&
typeof obj.title === 'string' &&
typeof obj.target === 'string' &&
typeof obj.bodyPart === 'string' &&
typeof obj.equipment === 'string' &&
Array.isArray(obj.images) &&
Array.isArray(obj.videos) &&
Array.isArray(obj.keywords)
);
}
function isExerciseData(obj: any): obj is IExerciseData {
return (
typeof obj === 'object' &&
typeof obj.totalExercises === 'number' &&
typeof obj.totalPages === 'number' &&
Array.isArray(obj.data) &&
obj.data.every(isValidExercise)
);
}