Skip to content

Instantly share code, notes, and snippets.

@a-type
Last active May 18, 2022 17:04
Show Gist options
  • Save a-type/8c6863e1d33698464e0f1f2405067c7e to your computer and use it in GitHub Desktop.
Save a-type/8c6863e1d33698464e0f1f2405067c7e to your computer and use it in GitHub Desktop.
Liveblocks API types
import {
LiveList,
LiveMap,
LiveObject,
Lson,
LsonObject,
} from '@liveblocks/client';
type ExtractObjectShape<T extends LiveObject<LsonObject>> =
T extends LiveObject<infer U> ? U : never;
type ExtractListShape<T extends LiveList<Lson>> = T extends LiveList<infer U>
? U
: never;
type ExtractMapShape<T extends LiveMap> = T extends LiveMap<infer X, infer U>
? Record<X, U>
: never;
type ApiJsonValues<T extends Record<string, any>> = {
[K in keyof T]: ApiJsonData<T[K]>;
};
type ApiJsonObject<T extends LiveObject> = {
liveblocksType: 'LiveObject';
data: ApiJsonValues<ExtractObjectShape<T>>;
};
type ApiJsonList<T extends LiveList> = {
liveblocksType: 'LiveList';
data: ApiJsonData<ExtractListShape<T>>[];
};
type ApiJsonMap<T extends LiveMap> = {
liveblocksType: 'LiveMap';
data: ApiJsonData<ExtractMapShape<T>>;
};
type ApiJsonData<T> = T extends LiveObject
? ApiJsonObject<T>
: T extends LiveList
? ApiJsonList<T>
: T extends LiveMap
? ApiJsonMap<T>
: T extends Record<string, any>
? ApiJsonValues<T>
: T extends Array<any>
? Array<ApiJsonData<T[number]>>
: T;
export type LiveblocksApiJson<
SourceData extends LiveObject | Record<string, any>,
> = ApiJsonData<SourceData>;
type MyLiveblocksStuff = LiveObject<{
foo: LiveMap<string, number>;
bar: LiveList<boolean>;
}>;
type MyJsonStuff = LiveblocksApiJson<MyLiveblocksStuff>;
/* it will look like:
{
liveblocksType: 'LiveObject',
data: {
foo: {
liveblocksType: 'LiveMap',
data: Record<string, number>;
},
bar: {
liveblocksType: 'LiveList',
data: boolean[];
},
},
};
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment