The Avala SDK is written in TypeScript and provides comprehensive type definitions for all API resources, making it easy to build type-safe applications.
Type safety benefits
The SDK provides full IntelliSense support and compile-time type checking:
import { Avala , Dataset } from '@avala-ai/sdk' ;
const avala = new Avala ({ apiKey: 'your-api-key' });
// TypeScript knows the return type is Dataset
const dataset : Dataset = await avala . datasets . get ( 'dataset-uid' );
// IntelliSense suggests available properties
console . log ( dataset . name );
console . log ( dataset . itemCount );
console . log ( dataset . createdAt );
Resource types
All resource types are exported from the SDK:
import type { Dataset } from '@avala-ai/sdk' ;
interface Dataset {
uid : string ;
name : string ;
slug : string ;
itemCount : number ;
dataType : string | null ;
createdAt : string | null ;
updatedAt : string | null ;
}
const dataset : Dataset = await avala . datasets . get ( 'dataset-uid' );
The SDK uses a generic CursorPage<T> type for paginated responses:
import type { CursorPage , Dataset } from '@avala-ai/sdk' ;
// Type is automatically inferred
const page = await avala . datasets . list ();
// Or explicitly typed
const typedPage : CursorPage < Dataset > = await avala . datasets . list ();
// Access typed items
for ( const dataset of page . items ) {
// TypeScript knows this is a Dataset
console . log ( dataset . name );
}
CursorPage definition
The pagination type is defined as:
export interface CursorPage < T > {
items : T [];
nextCursor : string | null ;
previousCursor : string | null ;
hasMore : boolean ;
}
Use the generic CursorPage<T> type when building pagination utilities.
Configuration types
The client configuration is fully typed:
import { Avala , type AvalaConfig } from '@avala-ai/sdk' ;
const config : AvalaConfig = {
apiKey: 'your-api-key' ,
baseUrl: 'https://api.avala.ai/api/v1' ,
timeout: 30000
};
const avala = new Avala ( config );
AvalaConfig interface
export interface AvalaConfig {
apiKey ?: string ;
baseUrl ?: string ;
timeout ?: number ;
}
All configuration properties are optional. The SDK will use environment variables and defaults when not provided.
Error types
All error classes are fully typed with specific properties:
Base error
Rate limit error
Validation error
import { AvalaError } from '@avala-ai/sdk' ;
try {
await avala . datasets . get ( 'dataset-uid' );
} catch ( error ) {
if ( error instanceof AvalaError ) {
// TypeScript knows these properties exist
const status : number | undefined = error . statusCode ;
const body : unknown = error . body ;
const message : string = error . message ;
}
}
Generic request helpers
Build type-safe wrappers using TypeScript generics:
import type { Avala , CursorPage } from '@avala-ai/sdk' ;
async function fetchAll < T >(
fetcher : ( cursor : string | null ) => Promise < CursorPage < T >>
) : Promise < T []> {
const items : T [] = [];
let cursor : string | null = null ;
do {
const page = await fetcher ( cursor );
items . push ( ... page . items );
cursor = page . nextCursor ;
} while ( cursor !== null );
return items ;
}
// Usage with type inference
const datasets = await fetchAll (( cursor ) =>
avala . datasets . list ({ cursor })
);
// TypeScript knows datasets is Dataset[]
console . log ( datasets [ 0 ]. name );
Complex types
The SDK includes types for complex nested structures:
import type { Agent } from '@avala-ai/sdk' ;
interface Agent {
uid : string ;
name : string ;
description : string | null ;
events : string [];
callbackUrl : string | null ;
isActive : boolean ;
project : string | null ;
taskTypes : string [];
createdAt : string | null ;
updatedAt : string | null ;
}
const agent : Agent = await avala . agents . get ( 'agent-uid' );
// Type-safe array access
const firstEvent : string = agent . events [ 0 ];
Type guards
Create type-safe guards for runtime checks:
import type { Dataset , Project } from '@avala-ai/sdk' ;
function isDataset ( resource : Dataset | Project ) : resource is Dataset {
return 'itemCount' in resource ;
}
function isProject ( resource : Dataset | Project ) : resource is Project {
return 'status' in resource ;
}
// Usage
const resource : Dataset | Project = await getResource ();
if ( isDataset ( resource )) {
// TypeScript knows this is a Dataset
console . log ( 'Items:' , resource . itemCount );
} else {
// TypeScript knows this is a Project
console . log ( 'Status:' , resource . status );
}
Null safety
Many properties are nullable in the API response:
import type { Dataset } from '@avala-ai/sdk' ;
const dataset : Dataset = await avala . datasets . get ( 'dataset-uid' );
// Handle nullable properties safely
const dataType : string = dataset . dataType ?? 'unknown' ;
if ( dataset . createdAt ) {
const created = new Date ( dataset . createdAt );
console . log ( 'Created:' , created . toLocaleDateString ());
}
// Optional chaining for nested nullable properties
const orgName = dataset . organization ?. name ?? 'No organization' ;
Always check for null values before using properties marked as string | null or number | null.
Type-safe request builders
Build composable, type-safe request utilities:
import type { Avala , Dataset , Project } from '@avala-ai/sdk' ;
class TypeSafeClient {
constructor ( private avala : Avala ) {}
async getResource < T extends Dataset | Project >(
type : 'dataset' | 'project' ,
uid : string
) : Promise < T > {
if ( type === 'dataset' ) {
return await this . avala . datasets . get ( uid ) as T ;
} else {
return await this . avala . projects . get ( uid ) as T ;
}
}
async listResources < T >(
fetcher : () => Promise < CursorPage < T >>
) : Promise < T []> {
const page = await fetcher ();
return page . items ;
}
}
const client = new TypeSafeClient ( avala );
// Type is inferred as Dataset
const dataset = await client . getResource < Dataset >( 'dataset' , 'uid' );
// Type is inferred as Dataset[]
const datasets = await client . listResources (() =>
avala . datasets . list ()
);
Best practices
Enable strict mode
Use strict TypeScript settings in your tsconfig.json: {
"compilerOptions" : {
"strict" : true ,
"strictNullChecks" : true ,
"noImplicitAny" : true ,
"esModuleInterop" : true
}
}
Import types explicitly
Use the type keyword for type-only imports: import { Avala } from '@avala-ai/sdk' ;
import type { Dataset , Project , CursorPage } from '@avala-ai/sdk' ;
Use type inference
Let TypeScript infer types when possible: // Good: Type is inferred
const dataset = await avala . datasets . get ( 'uid' );
// Unnecessary: Explicit type
const dataset : Dataset = await avala . datasets . get ( 'uid' );
Handle nullable properties
Always check for null values: const dataset = await avala . datasets . get ( 'uid' );
// Use nullish coalescing
const dataType = dataset . dataType ?? 'unknown' ;
// Use optional chaining
const createdDate = dataset . createdAt
? new Date ( dataset . createdAt )
: null ;
Leverage TypeScript’s IntelliSense in your IDE to discover available properties and methods.
Advanced patterns
Build sophisticated type-safe abstractions:
import type { Avala , CursorPage } from '@avala-ai/sdk' ;
type ResourceList < T > = () => Promise < CursorPage < T >>;
type ResourceGet < T > = ( uid : string ) => Promise < T >;
class Repository < T extends { uid : string }> {
constructor (
private list : ResourceList < T >,
private get : ResourceGet < T >
) {}
async findAll () : Promise < T []> {
const items : T [] = [];
let cursor : string | null = null ;
do {
const page = await this . list ();
items . push ( ... page . items );
cursor = page . nextCursor ;
} while ( cursor !== null );
return items ;
}
async findById ( uid : string ) : Promise < T > {
return await this . get ( uid );
}
async findByIds ( uids : string []) : Promise < T []> {
return await Promise . all (
uids . map ( uid => this . get ( uid ))
);
}
}
// Usage
const datasetRepo = new Repository (
() => avala . datasets . list (),
( uid ) => avala . datasets . get ( uid )
);
const allDatasets = await datasetRepo . findAll ();
const dataset = await datasetRepo . findById ( 'dataset-uid' );
Created 4 Guides pages successfully