Skip to content

Instantly share code, notes, and snippets.

@IrvingArmenta
Created April 10, 2021 02:46
Show Gist options
  • Save IrvingArmenta/4cbeeb45bf2c2e36df8026fffb90cc47 to your computer and use it in GitHub Desktop.
Save IrvingArmenta/4cbeeb45bf2c2e36df8026fffb90cc47 to your computer and use it in GitHub Desktop.
Typing for "Flattened" objects for "flat" objects
import flatten from "flat";
const OriginalObj = {
key1: 'key1Value',
key2: {
key2a: 'key2a value',
key2b: 3231
}
};
type U2I<U> = (U extends U ? (u: U) => 0 : never) extends (i: infer I) => 0 ? Extract<I, U> : never
type Separate<T, U> = [Extract<T, U>, Exclude<T, U>]
type UnionKeys<T> = T extends T ? keyof T : never
type XOR<T> = Expand<[T]|[T] extends [infer T_] ? T_ extends T ?
T_ & Partial<Record<Exclude<UnionKeys<T>, keyof T_>, never>>
: never : never>
type Expand<T> = T extends T ? { [K in keyof T]: T[K] } : never
type Flatten<T> =
T extends object
? XOR<U2I<NonNullable<{
[K in keyof T]: [
Separate<Flatten<T[K]>, object> extends [infer U, infer V]
? { -readonly [K2 in keyof U as `${K & string}.${K2 & string}`]: U[K2] }
| ([V] extends [never] ? never : Pick<{ -readonly [_ in keyof T]: V }, K>)
: never
]
}[keyof T]>>[0]>
: T
type X = Flatten<{
a?: 5,
b?: {
c: 9,
d?: 4,
}
}>;
type FlattenedObj = Flatten<typeof OriginalObj>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment