diff --git a/js/igv.d.ts b/js/igv.d.ts index db909dff9..0eb015065 100644 --- a/js/igv.d.ts +++ b/js/igv.d.ts @@ -4,10 +4,12 @@ type AnyCase = Uppercase | Lowercase; // any action that can be deferred as a promise or a thenable type Deferrable = T | Promise | Thenable | (() => T | Promise | Thenable); +// a custom future implementation supported by igv.js export interface Thenable { then(resolve: (value: T) => void, reject: (error: E) => void): void; } +// simply prevents the type from being inferred declare class Opaque { private readonly __opaque_brand: N; } @@ -18,6 +20,7 @@ export type TrackType = /* undocumented options */ "snp" | "eqtl"; +// converts a track type into the options needed to create it export type TrackLoad = Tracks.TrackCommonOptions & (T extends "annotation" ? Tracks.AnnotationTrackOptions & TypeFormatPair<'annotation'> : @@ -40,23 +43,27 @@ export type TrackLoad = export type TypeFormatPair = { type?: T; + // if we know the format, type is not required format: TrackFormatOf; url?: string; } | { type?: T; format?: TrackFormatOf; + // if we can infer the URL, we do not need type or format url: TrackFormatOf extends string ? Deferrable>> : never; } | ({ - type?: T; + // an explicit type and manual reader is allowed, however format and url will not make sense in this context + type: T; format?: never; url?: never; } & (CustomReaderOf | ManualFeatureOf)) | { type: T; format?: TrackFormatOf; - // if there is only one possible format, we permit it to be omitted - url: TrackFormatOf extends string ? (string extends TrackFormatOf ? never : string) : never; + // if there is only one possible format, we permit format to be omitted + url: TrackFormatOf extends string ? (string extends TrackFormatOf ? never : Deferrable>>) : never; }; +// converts a track type into the file formats that it can accept export type TrackFormatOf = T extends "annotation" ? Tracks.AnnotationFormat : T extends "wig" ? Tracks.WigFormat : @@ -75,6 +82,7 @@ export type TrackFormatOf = T extends "eqtl" ? Tracks.EQTLFormat : never; +// converts a track type into the manual features that it can accept export type ManualFeatureOf = T extends "annotation" ? { features: Record[]; @@ -83,15 +91,16 @@ export type ManualFeatureOf = features: Tracks.WigTrackManualFeatures; } : T extends "seg" ? { - features: Array<{ + features: { chr: string; start: number; end: number; value: number; sample: string; - }>; + }[]; } : never; +// some tracks can support a custom reader that polls data based on options export type CustomReaderOf = T extends "annotation" ? { reader: Tracks.AnnotationCustomReader } | { @@ -113,6 +122,7 @@ export type CustomReaderOf = } : never; +// converts a track type into the actual track class export type TrackOf = T extends "annotation" ? Tracks.Track : T extends "wig" ? Tracks.Track : @@ -151,10 +161,12 @@ export namespace URLInference { type AuxExtensions = ".gz" | ".tab" | ".txt" | ".bgz"; + // infer the extension of a URL, with auxillary extensions stripped export type InferExtension = Lowercase extends `${infer B}${AuxExtensions}` ? StripLast : StripLast, '.'> type Query = `?${string}`; + // matches a URL with an extension export type URLWithExtension = `${string}.${E}${AuxExtensions | ''}${Query | ''}`; } @@ -370,7 +382,7 @@ export namespace Tracks { * * @type {object} */ - guidelines?: Array<{ color: string, y: number, dotted: boolean }>; + guidelines?: { color: string, y: number, dotted: boolean }[]; /** * Type of graph, either "bar" or "points" * @@ -634,8 +646,6 @@ export namespace Tracks { } type Nucleotide = 'A' | 'C' | 'G' | 'T' | 'N'; -type AnnotationFormat = 'bed' | 'gff3' | 'gtf' | 'genePred' | 'genePredExt' | 'peaks' | 'narrowPeak' | 'broadPeak' | 'bigBed' | 'bedpe'; - type HostedGenomes = "hs1" | "chm13v1.1" | "hg38" | "hg38_1kg" | "hg19" | "hg18" | "mm39" | "mm10" | "mm9" | "rn7" | @@ -788,6 +798,7 @@ interface CreateOptExtras { export namespace BrowserEvents { export type EventType = "trackremoved" | "trackdrag" | "trackdragend" | "locuschange" | "trackclick" | "trackorderchanged"; + // returns the type of the event handler based on the event type export type EventHandler = T extends "trackremoved" ? (tracks: Tracks.Track[]) => EventReturn : T extends "locusChange" ? (loci: { @@ -809,6 +820,7 @@ export namespace BrowserEvents { } export type CreateOpt = (GenomeOpt & CreateOptExtras) | ( + // if a session URL is provided, we do not need a complete definition, additionally we should not allow a different genome { sessionURL: string; } & Partial