Skip to content

InferType

Extracts the interface type bound to an InterfaceId, SyncIID, or AsyncIID token.

Signature

type InferType<T extends InterfaceId<any, any>> = NonNullable<T['_type']>

Parameters

ParameterTypeDescription
TInterfaceId<any, any>An IID token type from syncIID<T>() or asyncIID<T>()

Returns: The interface type T that was bound to the IID.

Examples

Basic Usage

import { syncIID, asyncIID, InferType } from "@asimojs/asimo";
interface Logger { log(msg: string): void; }
const LOGGER = syncIID<Logger>()("app.Logger");
interface Database { query(sql: string): Promise<any[]>; }
const DB = asyncIID<Database>()("app.Database");
type LoggerType = InferType<typeof LOGGER>; // Logger
type DBType = InferType<typeof DB>; // Database

Class Field Annotations

When a class stores dependencies eagerly in the constructor, use InferType to annotate fields without importing the original interfaces:

class UserService {
private db: InferType<typeof DB>;
private logger: InferType<typeof LOGGER>;
constructor(context: Container<typeof DB | typeof LOGGER>) {
this.db = context.get(DB);
this.logger = context.get(LOGGER);
}
}

Factory Return Types

function createLogger(
context: Container<typeof DB>,
): InferType<typeof LOGGER> {
const db = context.get(DB);
return {
log: (msg: string) => db.query(`INSERT INTO logs: ${msg}`),
};
}

How It Works

InferType reads the phantom _type field on the IID token. This field is never set at runtime — it only exists to make the TypeScript type structural:

// Internally:
interface SyncIID<T, NS extends string = string> {
ns: NS;
sync: true;
readonly _type?: T; // ← NonNullable<'T | undefined'> → T
}

Since _type is optional (_type?), its type is T | undefined. NonNullable strips the undefined, yielding T.