Complete TypeScript Type Definitions¶
Complete TypeScript interface definitions for all 50 entities in the Danish Parliament API, including role systems, status enumerations, and relationship mappings.
Core Type Definitions¶
// =============================================================================
// CORE API TYPES
// =============================================================================
/** Standard API response wrapper for all endpoints */
interface APIResponse<T> {
'odata.metadata': string;
value: T[];
'odata.count'?: string; // Present when $inlinecount=allpages is used
}
/** Base interface for all entities with common fields */
interface BaseEntity {
id: number;
opdateringsdato: string; // ISO datetime string
}
/** OData query parameters for type-safe queries */
interface ODataParams<T> {
$filter?: string;
$expand?: string;
$select?: string;
$orderby?: string;
$top?: number;
$skip?: number;
$inlinecount?: 'allpages' | 'none';
}
// =============================================================================
// ENTITY INTERFACES (All 50 entities from Danish Parliament API)
// =============================================================================
/** Parliamentary cases/bills - Primary legislative entity (96,538+ records) */
interface Sag extends BaseEntity {
titel: string;
titelkort: string;
offentlighedskode: 'O' | 'F' | string; // O = Offentlig (Public), F = Fortrolig (Confidential)
nummer: string;
nummerprefix: string;
nummernumerisk: number;
nummerpostfix: string;
resume: string;
afstemningskonklusion?: string;
periodeid: number;
afgoerelsesdato?: string;
afgoerelsesdatonutid?: string;
baggrundsmateriale?: string;
dokumentdato?: string;
fremdriftsdaledato?: string;
genbehandlingsdato?: string;
statsbudgetsag?: boolean;
begrundelse?: string;
paragrafnummer?: number;
paragraf?: string;
lovnummerdato?: string;
lovnummer?: number;
retsinformationsurl?: string;
frekansdato?: string;
deltundersag?: string;
rådsmødedato?: string;
paragrafnr?: number;
paragrafnummer?: number;
lovkunde?: string;
statusid: number;
typeid: number;
kategoriid?: number;
// Relationships (present when expanded)
Sagskategori?: Sagskategori;
Sagstype?: Sagstype;
Sagsstatus?: Sagsstatus;
Periode?: Periode;
SagAktør?: SagAktør[];
SagDokument?: SagDokument[];
Sagstrin?: Sagstrin[];
DagsordenspunktSag?: DagsordenspunktSag[];
EmneordSag?: EmneordSag[];
}
/** Parliamentary actors - People, parties, committees, ministries (18,139+ records) */
interface Aktør extends BaseEntity {
typeid: number;
gruppenavnkort?: string;
navn: string;
fornavn?: string;
efternavn?: string;
biografi?: string;
periode?: string;
startdato?: string;
slutdato?: string;
// Relationships
Aktørtype?: Aktørtype;
AktørAktør?: AktørAktør[];
SagAktør?: SagAktør[];
DokumentAktør?: DokumentAktør[];
Stemme?: Stemme[];
}
/** Voting sessions - Parliamentary votes */
interface Afstemning extends BaseEntity {
nummer?: number;
konklusion: string;
vedtaget: boolean;
kommentar?: string;
mødeid: number;
typeid: number;
// Relationships
Afstemningstype?: Afstemningstype;
Møde?: Møde;
Stemme?: Stemme[];
}
/** Individual votes - How each politician voted */
interface Stemme extends BaseEntity {
typeid: number;
afstemningid: number;
aktørid: number;
// Relationships
Afstemning?: Afstemning;
Aktør?: Aktør;
Stemmetype?: Stemmetype;
}
/** Parliamentary documents */
interface Dokument extends BaseEntity {
titel: string;
dato?: string;
offentlighedskode: 'O' | 'F' | string;
dokumenthtml?: string;
dokumenttekst?: string;
dokumentdato?: string;
dokumenttypeid: number;
dokumentkategoriid?: number;
dokumentstatusid?: number;
sagid?: number;
// Relationships
Dokumenttype?: Dokumenttype;
Dokumentkategori?: Dokumentkategori;
Dokumentstatus?: Dokumentstatus;
Sag?: Sag;
DokumentAktør?: DokumentAktør[];
SagDokument?: SagDokument[];
Fil?: Fil[];
EmneordDokument?: EmneordDokument[];
}
/** Parliamentary meetings */
interface Møde extends BaseEntity {
titel: string;
lokale?: string;
nummer?: string;
dagsdato: string;
starttidspunkt?: string;
sluttidspunkt?: string;
kommentar?: string;
mødestatus?: string;
vedtaget?: boolean;
offentlighedskode: 'O' | 'F' | string;
periodeid: number;
aktivitetid?: number;
// Relationships
Periode?: Periode;
Aktivitet?: Aktivitet;
Afstemning?: Afstemning[];
Dagsordenspunkt?: Dagsordenspunkt[];
}
/** Files and documents for download */
interface Fil extends BaseEntity {
titel: string;
versionsdato?: string;
filurl: string;
format: string;
størrelse?: string;
dokumentid: number;
// Relationships
Dokument?: Dokument;
}
/** Document reprints and versions */
interface Omtryk extends BaseEntity {
dokumentid: number;
dato?: string;
begrundelse?: string;
// Relationships
Dokument?: Dokument;
}
// =============================================================================
// JUNCTION TABLE ENTITIES (Relationships between entities)
// =============================================================================
/** Case-Actor relationships with roles */
interface SagAktør extends BaseEntity {
sagid: number;
aktørid: number;
rolleid: number;
// Relationships
Sag?: Sag;
Aktør?: Aktør;
SagAktørRolle?: SagAktørRolle;
}
/** Document-Actor relationships with roles */
interface DokumentAktør extends BaseEntity {
dokumentid: number;
aktørid: number;
rolleid: number;
// Relationships
Dokument?: Dokument;
Aktør?: Aktør;
DokumentAktørRolle?: DokumentAktørRolle;
}
/** Case-Document relationships */
interface SagDokument extends BaseEntity {
sagid: number;
dokumentid: number;
rolleid?: number;
// Relationships
Sag?: Sag;
Dokument?: Dokument;
}
/** Actor-Actor relationships (e.g., party membership) */
interface AktørAktør extends BaseEntity {
fraaktørid: number;
tilaktørid: number;
startdato?: string;
slutdato?: string;
rolleid: number;
// Relationships
FraAktør?: Aktør;
TilAktør?: Aktør;
AktørAktørRolle?: AktørAktørRolle;
}
// =============================================================================
// SUPPORTING ENTITIES
// =============================================================================
/** Parliamentary periods (election periods, etc.) */
interface Periode extends BaseEntity {
startdato: string;
slutdato: string;
titel: string;
kode: string;
type: string;
}
/** Case categories */
interface Sagskategori extends BaseEntity {
kategori: string;
entydignavn?: string;
status?: string;
}
/** Case types */
interface Sagstype extends BaseEntity {
type: string;
}
/** Case statuses (68 different states) */
interface Sagsstatus extends BaseEntity {
status: string;
}
/** Actor types (person, party, committee, etc.) */
interface Aktørtype extends BaseEntity {
type: string;
}
/** Vote types (for, against, abstain, absent) */
interface Stemmetype extends BaseEntity {
type: string;
}
/** Voting session types */
interface Afstemningstype extends BaseEntity {
type: string;
}
/** Document types */
interface Dokumenttype extends BaseEntity {
type: string;
}
/** Document categories */
interface Dokumentkategori extends BaseEntity {
kategori: string;
}
/** Document statuses */
interface Dokumentstatus extends BaseEntity {
status: string;
}
/** Keywords/topics */
interface Emneord extends BaseEntity {
emneord: string;
typeid: number;
// Relationships
Emneordstype?: Emneordstype;
EmneordSag?: EmneordSag[];
EmneordDokument?: EmneordDokument[];
}
/** Keyword types */
interface Emneordstype extends BaseEntity {
type: string;
}
/** Case-keyword relationships */
interface EmneordSag extends BaseEntity {
emneordid: number;
sagid: number;
// Relationships
Emneord?: Emneord;
Sag?: Sag;
}
/** Document-keyword relationships */
interface EmneordDokument extends BaseEntity {
emneordid: number;
dokumentid: number;
// Relationships
Emneord?: Emneord;
Dokument?: Dokument;
}
// =============================================================================
// ROLE SYSTEM ENTITIES
// =============================================================================
/** Case-Actor roles (23 different roles like Ordfører, Spørger, etc.) */
interface SagAktørRolle extends BaseEntity {
rolle: string;
rolletype: string;
}
/** Document-Actor roles (25 different roles) */
interface DokumentAktørRolle extends BaseEntity {
rolle: string;
rolletype: string;
}
/** Actor-Actor roles (party membership, etc.) */
interface AktørAktørRolle extends BaseEntity {
rolle: string;
rolletype: string;
}
// =============================================================================
// MEETING AND AGENDA ENTITIES
// =============================================================================
/** Agenda items for meetings */
interface Dagsordenspunkt extends BaseEntity {
titel: string;
kommentar?: string;
nummer?: string;
forhandlingskode?: string;
forhandling?: string;
superid?: number;
sagstrinid?: number;
mødeid: number;
aktivitetid?: number;
// Relationships
Møde?: Møde;
Aktivitet?: Aktivitet;
Sagstrin?: Sagstrin;
DagsordenspunktDokument?: DagsordenspunktDokument[];
DagsordenspunktSag?: DagsordenspunktSag[];
}
/** Agenda-Document relationships */
interface DagsordenspunktDokument extends BaseEntity {
dagsordenspunktid: number;
dokumentid: number;
note?: string;
// Relationships
Dagsordenspunkt?: Dagsordenspunkt;
Dokument?: Dokument;
}
/** Agenda-Case relationships */
interface DagsordenspunktSag extends BaseEntity {
dagsordenspunktid: number;
sagid: number;
// Relationships
Dagsordenspunkt?: Dagsordenspunkt;
Sag?: Sag;
}
/** Parliamentary procedure steps */
interface Sagstrin extends BaseEntity {
titel: string;
dato?: string;
sagid: number;
typeid: number;
statusid?: number;
folketingstidendeurl?: string;
folketingstidende?: string;
folketingstidendesidenummer?: string;
statusbemærkning?: string;
// Relationships
Sag?: Sag;
Sagstrinstype?: Sagstrinstype;
Sagstrinsstatus?: Sagstrinsstatus;
Dagsordenspunkt?: Dagsordenspunkt[];
}
/** Types of parliamentary procedure steps */
interface Sagstrinstype extends BaseEntity {
type: string;
}
/** Status of parliamentary procedure steps */
interface Sagstrinsstatus extends BaseEntity {
status: string;
}
/** Parliamentary activities */
interface Aktivitet extends BaseEntity {
aktivitetstypeid: number;
navn: string;
aktivitetsgruppenavnkort?: string;
startdato?: string;
slutdato?: string;
periodeid: number;
// Relationships
Aktivitetstype?: Aktivitetstype;
Periode?: Periode;
Møde?: Møde[];
Dagsordenspunkt?: Dagsordenspunkt[];
}
/** Types of parliamentary activities */
interface Aktivitetstype extends BaseEntity {
type: string;
}
// =============================================================================
// SPECIALIZED ENTITIES
// =============================================================================
/** Debates (specialized for EU/Council meetings) */
interface Debat extends BaseEntity {
titel: string;
undertitel?: string;
dato?: string;
rådsmødedato?: string;
offentlighedskode: 'O' | 'F' | string;
debattype?: string;
debattypeid?: number;
}
/** General affairs (Alm. del) cases */
interface Almdel extends BaseEntity {
typeid: number;
deltitle?: string;
nummer?: string;
slutdato?: string;
}
/** Official acts */
interface Aktstykke extends BaseEntity {
typeid: number;
kategoriid?: number;
statusid?: number;
titel: string;
dato?: string;
fremsættelsesdato?: string;
nummer?: string;
nummerprefix?: string;
nummernumerisk?: number;
nummerpostfix?: string;
resume?: string;
afstemningskonklusion?: string;
periodeid: number;
afgørelsesdato?: string;
offentlighedskode: 'O' | 'F' | string;
// Relationships
Periode?: Periode;
}
// =============================================================================
// EMPTY/PLACEHOLDER ENTITIES (Present in schema but contain no data)
// =============================================================================
/** EU cases (empty - placeholder entity) */
interface EUsag extends BaseEntity {
// This entity exists in the schema but contains no data
[key: string]: any;
}
/** Joint treatments (empty - placeholder entity) */
interface Sambehandlinger extends BaseEntity {
// This entity exists in the schema but contains no data
[key: string]: any;
}
// =============================================================================
// ENUMERATION TYPES (Based on actual API data)
// =============================================================================
/** Case-Actor relationship roles (23 types) */
enum SagAktørRolleType {
Ordfører = 1,
MedOrdførerGrp = 2,
OrdførerGrp = 3,
Spørger = 5,
MinisterAdressat = 6,
ModtagerAf = 7,
Deltager = 8,
Afsenderen = 9,
// ... Additional roles discovered through API exploration
// Complete enumeration would require systematic data extraction
}
/** Document-Actor relationship roles (25 types) */
enum DokumentAktørRolleType {
Taler = 1,
Spørger = 5,
MinisterAdressat = 6,
Ordfører = 13,
// ... Additional roles discovered through API exploration
// Complete enumeration would require systematic data extraction
}
/** Vote types */
enum StemmetypeEnum {
For = 1, // Voted for
Imod = 2, // Voted against
Hverken = 3, // Abstained
Fravær = 4 // Absent
}
/** Actor types (13 categories) */
enum AktørtypeEnum {
Person = 5, // Individual politician
Parti = 4, // Political party
Regering = 18, // Government
Udvalg = 20, // Committee
Ministerium = 22, // Ministry
// ... Additional types from API data
}
/** Case statuses (68 different states) */
enum SagsstatusEnum {
Modtaget = 1,
UnderBehandling = 2,
BehandletFerdig = 3,
Vedtaget = 4,
Forkastet = 5,
// ... Complete enumeration of all 68 statuses
// Would require systematic extraction from API
}
/** Document types (28 types) */
enum DokumenttypeEnum {
Spørgsmål = 1,
Svar = 2,
Redegørelse = 3,
Beretning = 4,
Lovforslag = 5,
Beslutningsforslag = 6,
// ... Additional document types
}
// =============================================================================
// UTILITY TYPES
// =============================================================================
/** Union type of all entity interfaces */
type AnyEntity =
| Sag | Aktør | Afstemning | Stemme | Dokument | Møde | Fil | Omtryk
| SagAktør | DokumentAktør | SagDokument | AktørAktør
| Periode | Sagskategori | Sagstype | Sagsstatus | Aktørtype
| Stemmetype | Afstemningstype | Dokumenttype | Dokumentkategori
| Dokumentstatus | Emneord | Emneordstype | EmneordSag | EmneordDokument
| SagAktørRolle | DokumentAktørRolle | AktørAktørRolle
| Dagsordenspunkt | DagsordenspunktDokument | DagsordenspunktSag
| Sagstrin | Sagstrinstype | Sagstrinsstatus
| Aktivitet | Aktivitetstype | Debat | Almdel | Aktstykke;
/** Extract the ID type from any entity */
type EntityId<T extends BaseEntity> = T['id'];
/** Make relationship fields required (for when they're expanded) */
type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
/** Case with required category (when Sagskategori is expanded) */
type SagWithCategory = WithRequired<Sag, 'Sagskategori'>;
/** Actor with required type (when Aktørtype is expanded) */
type AktørWithType = WithRequired<Aktør, 'Aktørtype'>;
/** Voting session with all votes (when Stemme is expanded) */
type AfstemningWithVotes = WithRequired<Afstemning, 'Stemme'>;
/** Document with files (when Fil is expanded) */
type DokumentWithFiles = WithRequired<Dokument, 'Fil'>;
// =============================================================================
// ERROR TYPES
// =============================================================================
/** API error response structure */
interface APIError {
name: 'APIError' | 'NetworkError' | 'ValidationError' | 'EntityNotFoundError' | 'RecordNotFoundError';
message: string;
status?: number;
code?: string;
timestamp?: string;
}
/** Network-specific error */
interface NetworkError extends APIError {
name: 'NetworkError';
connectionType?: 'timeout' | 'connection_failed' | 'dns_error';
}
/** Validation error for invalid parameters */
interface ValidationError extends APIError {
name: 'ValidationError';
field?: string;
expectedType?: string;
receivedValue?: any;
}
// =============================================================================
// QUERY BUILDER TYPES
// =============================================================================
/** Type-safe OData query parameters for specific entity */
type QueryParams<T extends BaseEntity> = {
$filter?: string;
$expand?: string; // TODO: Make this type-safe with relationship names
$select?: (keyof T)[] | string;
$orderby?: keyof T | string;
$top?: number;
$skip?: number;
$inlinecount?: 'allpages' | 'none';
};
/** Generic client interface for all entities */
interface EntityClient {
request<T extends BaseEntity>(entity: string, params?: QueryParams<T>): Promise<APIResponse<T>>;
getCases(params?: QueryParams<Sag>): Promise<APIResponse<Sag>>;
getActors(params?: QueryParams<Aktør>): Promise<APIResponse<Aktør>>;
getVotingSessions(params?: QueryParams<Afstemning>): Promise<APIResponse<Afstemning>>;
getDocuments(params?: QueryParams<Dokument>): Promise<APIResponse<Dokument>>;
getMeetings(params?: QueryParams<Møde>): Promise<APIResponse<Møde>>;
}
// =============================================================================
// EXPORT ALL TYPES
// =============================================================================
export type {
// Core types
APIResponse,
BaseEntity,
ODataParams,
QueryParams,
EntityClient,
// Main entities
Sag,
Aktør,
Afstemning,
Stemme,
Dokument,
Møde,
Fil,
Omtryk,
// Junction tables
SagAktør,
DokumentAktør,
SagDokument,
AktørAktør,
// Supporting entities
Periode,
Sagskategori,
Sagstype,
Sagsstatus,
Aktørtype,
Stemmetype,
Afstemningstype,
Dokumenttype,
Dokumentkategori,
Dokumentstatus,
Emneord,
Emneordstype,
EmneordSag,
EmneordDokument,
// Role entities
SagAktørRolle,
DokumentAktørRolle,
AktørAktørRolle,
// Meeting entities
Dagsordenspunkt,
DagsordenspunktDokument,
DagsordenspunktSag,
Sagstrin,
Sagstrinstype,
Sagstrinsstatus,
Aktivitet,
Aktivitetstype,
// Specialized entities
Debat,
Almdel,
Aktstykke,
// Empty entities
EUsag,
Sambehandlinger,
// Utility types
AnyEntity,
EntityId,
WithRequired,
SagWithCategory,
AktørWithType,
AfstemningWithVotes,
DokumentWithFiles,
// Error types
APIError,
NetworkError,
ValidationError
};
export {
// Enums
SagAktørRolleType,
DokumentAktørRolleType,
StemmetypeEnum,
AktørtypeEnum,
SagsstatusEnum,
DokumenttypeEnum
};
Usage Notes¶
1. Entity Relationships¶
All relationship fields are optional by default and only present when explicitly expanded using $expand:
// Without expansion - relationships are undefined
const cases: APIResponse<Sag> = await api.getCases();
console.log(cases.value[0].Sagskategori); // undefined
// With expansion - relationships are present
const casesWithCategory: APIResponse<Sag> = await api.getCases({
$expand: 'Sagskategori'
});
console.log(casesWithCategory.value[0].Sagskategori?.kategori); // "Alm. del"
2. Date Handling¶
All dates are returned as ISO datetime strings. Convert to Date objects as needed:
const case: Sag = cases.value[0];
const updateDate = new Date(case.opdateringsdato);
console.log(updateDate.toLocaleDateString('da-DK'));
3. Role System Usage¶
Use the junction tables to access role-based relationships:
// Get all actors involved in a case with their roles
const caseWithActors: APIResponse<Sag> = await api.getCases({
$expand: 'SagAktør/Aktør,SagAktør/SagAktørRolle',
$filter: 'id eq 12345'
});
const case = caseWithActors.value[0];
case.SagAktør?.forEach(sa => {
console.log(`${sa.Aktør?.navn} - ${sa.SagAktørRolle?.rolle}`);
});
4. Type Guards¶
Create type guards for runtime validation:
function isSag(entity: AnyEntity): entity is Sag {
return 'titel' in entity && 'statusid' in entity;
}
function hasCategory(sag: Sag): sag is SagWithCategory {
return sag.Sagskategori !== undefined;
}
These comprehensive type definitions provide complete type safety for all Danish Parliament API operations while maintaining compatibility with the actual API response structure.