@croct/plug
Version:
A fully-featured devkit for building natively personalized applications.
27 lines (24 loc) • 1.22 kB
text/typescript
import { JsonObject } from '@croct/json';
type LatestAlias = 'latest';
type CanonicalVersionId<I extends string, M> = {
[K in I]: `${K}@${Extract<Version<M, K>, `${number}`>}`;
}[I];
/**
* Utility type that coerces any type to a string if it is not a string literal.
*/
type CastString<T extends string> = T extends `${infer V}` ? V : string;
type VersionedId<I extends string, M> = CastString<I> | {
[K in I]: `${K}@${Version<M, K> & string}`;
}[I];
type Version<M, I extends string> = LatestAlias | (I extends keyof M ? keyof M[I] : never);
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type Expand<T> = {
[K in keyof T]: T[K];
};
type FlattenVersionMap<T> = Expand<UnionToIntersection<{
[K in Extract<keyof T, string>]: {
[K2 in Extract<keyof T[K], string> as (`${K}@${K2}` | (LatestAlias extends K2 ? K : never))]: T[K][K2];
};
}[Extract<keyof T, string>]>>;
type Versioned<I extends string, M, C extends JsonObject = JsonObject> = I extends `${infer K}` ? K extends keyof FlattenVersionMap<M> ? FlattenVersionMap<M>[K] : C : C;
export type { CanonicalVersionId, LatestAlias, Version, Versioned, VersionedId };