Type Helpers Guide
The SportMonks TypeScript SDK includes utility types and functions to make working with API responses even more type-safe.
Type Guards
hasInclude()
Check if an optional include is present and get proper type inference:
import { hasInclude } from '@withqwerty/sportmonks-typescript-sdk';
const team = await client.teams.byId(1).include(['country', 'venue']).get();
if (hasInclude(team.data, 'country')) {
// TypeScript now knows team.data.country is defined
console.log(team.data.country.name); // ✅ No type errors
}
hasData()
Type guard for responses with data:
import { hasData } from '@withqwerty/sportmonks-typescript-sdk';
const response = await client.teams.byId(1).get();
if (hasData(response)) {
// TypeScript knows response.data exists
console.log(response.data.name);
}
isPaginatedResponse()
/ isSingleResponse()
Distinguish between response types:
import { isPaginatedResponse, isSingleResponse } from '@withqwerty/sportmonks-typescript-sdk';
const response = await client.teams.all().get();
if (isPaginatedResponse(response)) {
// response.data is Team[]
response.data.forEach(team => console.log(team.name));
} else if (isSingleResponse(response)) {
// response.data is Team
console.log(response.data.name);
}
Type Helpers
ExtractData<T>
Extract the data type from any response:
import {
ExtractData,
SingleResponse,
PaginatedResponse
} from '@withqwerty/sportmonks-typescript-sdk';
type TeamData = ExtractData<SingleResponse<Team>>; // Team
type TeamsData = ExtractData<PaginatedResponse<Team>>; // Team[]
WithRequired<T, K>
Make optional properties required when you know they’re included:
import { WithRequired, Team } from '@withqwerty/sportmonks-typescript-sdk';
// Make country required on Team type
type TeamWithCountry = WithRequired<Team, 'country'>;
// Make multiple properties required
type TeamWithAll = WithRequired<Team, 'country' | 'venue' | 'coach'>;
Pre-defined Include Types
Common include combinations are pre-defined for convenience:
import {
TeamWithCountry,
TeamWithVenue,
TeamWithAll,
FixtureWithTeams,
FixtureWithEvents,
PlayerWithTeam
} from '@withqwerty/sportmonks-typescript-sdk';
// Use in your functions
function processTeamWithCountry(team: TeamWithCountry) {
// country is guaranteed to exist
console.log(`${team.name} from ${team.country.name}`);
}
Utility Functions
getNestedInclude()
Safely access nested include properties:
import { getNestedInclude } from '@withqwerty/sportmonks-typescript-sdk';
const team = await client.teams.byId(1).include(['country']).get();
// Safe access - returns undefined if not present
const countryName = getNestedInclude(team.data, 'country', 'name');
const countryCode = getNestedInclude(team.data, 'country', 'code');
Filter Helpers
Type-safe filter functions:
import { isNationalTeam } from '@withqwerty/sportmonks-typescript-sdk';
const teams = await client.teams.all().get();
const nationalTeams = teams.data.filter(isNationalTeam);
Sort Helpers
Type-safe sorting functions:
import { sortByName, sortByCapacity } from '@withqwerty/sportmonks-typescript-sdk';
// Sort teams by name
const sortedTeams = teams.data.sort(sortByName);
// Sort venues by capacity (descending)
const sortedVenues = venues.data.sort(sortByCapacity);
Response Transformers
Create typed transformers for responses:
import { createTransformer, PaginatedResponse, Team } from '@withqwerty/sportmonks-typescript-sdk';
// Create a transformer that extracts team names
const toTeamNames = createTransformer<PaginatedResponse<Team>, string[]>(response =>
response.data.map(team => team.name)
);
// Use it
const response = await client.teams.all().get();
const names = toTeamNames(response); // string[]
Complete Example
Here’s how to use multiple type helpers together:
import {
SportMonksClient,
hasInclude,
isPaginatedResponse,
TeamWithCountry,
sortByName
} from '@withqwerty/sportmonks-typescript-sdk';
const client = new SportMonksClient(API_KEY);
async function getTeamsByCountry(countryName: string) {
const response = await client.teams.all().include(['country']).perPage(100).get();
if (!isPaginatedResponse(response)) {
throw new Error('Unexpected response type');
}
// Filter teams with type safety
const teamsFromCountry = response.data.filter((team): team is TeamWithCountry => {
return hasInclude(team, 'country') && team.country.name === countryName;
});
// Sort and return
return teamsFromCountry.sort(sortByName);
}
// Usage
const englishTeams = await getTeamsByCountry('England');
englishTeams.forEach(team => {
console.log(`${team.name} - ${team.country.name}`); // ✅ Type safe!
});
Benefits
- Type Safety: Eliminate runtime errors from accessing undefined includes
- Better IntelliSense: Get proper autocomplete for included properties
- Cleaner Code: Use type guards instead of manual checks
- Reusability: Pre-defined types for common include patterns