Skip to content

Instantly share code, notes, and snippets.

@all-you-need-is-laugh
Created May 3, 2024 23:54
Show Gist options
  • Save all-you-need-is-laugh/7408612deb9d56e3808aac2175482434 to your computer and use it in GitHub Desktop.
Save all-you-need-is-laugh/7408612deb9d56e3808aac2175482434 to your computer and use it in GitHub Desktop.
TypeORM entity relations type
// LIBRARY TYPES
type _Arr<N, Result extends number[] = []> = Result['length'] extends N ? Result : _Arr<N, [...Result, 1]>;
type _Decrement<N extends number> = _Arr<N> extends [any, ...infer U] ? U['length'] : 0;
type _Concat<S1 extends string, S2 extends string> = [S1] extends [never]
? [S2] extends [never]
? ''
: S2
: [S2] extends [never]
? S1
: `${S1}.${S2}`
type _StringKeys<T> = Exclude<keyof T, symbol | number>
type _ArrayElement<T> = T extends (infer E)[] ? E : T;
type _RelationValue<TObject extends object, TDepth extends number, TPath extends string> =
TDepth extends 0
? TPath
: TPath | _RelationPaths<_ArrayElement<TObject>, _Decrement<TDepth>, TPath>
type _RelationMapping<T, TDepth extends number, TPrefix extends string> = {
[P in _StringKeys<T>]: T[P] extends object
? _RelationValue<T[P], TDepth, _Concat<TPrefix, P>>
: never;
}
type _RelationPaths<T, TDepth extends number, TPrefix extends string> = _RelationMapping<T, TDepth, TPrefix>[_StringKeys<T>]
type Relations<T, TDepth extends number = 3> = _RelationPaths<T, TDepth, never>;
// APPLICATION TYPES FOR TEST
type Appartments = {
room: number;
persons: User[];
}
type Address = {
country: string;
appartments: Appartments;
}
type User = {
name: string;
address: Address;
}
type UserRelations = Relations<User>;
const relations: UserRelations[] = [
'name',
'address',
'appartments',
'address.country',
'address.appartments',
'address.appartments.persons',
'address.appartments.persons.age',
'address.appartments.persons.address',
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment