Skip to content

Instantly share code, notes, and snippets.

@WomB0ComB0
Created November 30, 2024 23:17
Show Gist options
  • Save WomB0ComB0/a66f336fc8c998d8ada3e1749a8ef25c to your computer and use it in GitHub Desktop.
Save WomB0ComB0/a66f336fc8c998d8ada3e1749a8ef25c to your computer and use it in GitHub Desktop.
Extract the types and properties from input literal/type/tuple of types
type Decrement<N extends number> = [
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19
][N];
type ExtractNthProperty<T, N extends number> =
T extends readonly [infer First, ...infer Rest]
? N extends 0
? First
: ExtractNthProperty<Rest, Decrement<N>>
: never;
type ExtractPropertyByName<T, K extends keyof T> = T[K];
declare module 'typescript' {
namespace BooleanLiteral {
type yes = true;
type no = false;
}
}
type Male = { gender: 'male'; age: number };
type Female = { gender: 'female'; salary: number };
type NonBinary = { gender: 'non-binary'; pronouns: string };
type Hermaphrodite = { gender: 'hermaphrodite'; pronouns: string };
type Asexual = { gender: 'asexual'; hydra: (answer: boolean) => boolean };
type Trans = {
gender: 'trans';
thighHighs: (answer: BooleanLiteral.yes | BooleanLiteral.no) => boolean;
};
type Person = Male | Female | NonBinary | Hermaphrodite | Asexual | Trans;
type TestTuple = ExtractNthProperty<
[Male, Female, NonBinary, Hermaphrodite, Asexual, Trans],
5
>; // Trans
type TestSingle = ExtractNthProperty<
[Person, Female, NonBinary, Hermaphrodite, Asexual, Trans],
0
>; // Person
type TestAsexual = ExtractNthProperty<[Asexual], 0>; // Asexual
type AsexualHydra = ExtractPropertyByName<Asexual, 'hydra'>; // (answer: boolean) => boolean
type HermaphroditePronouns = ExtractPropertyByName<Hermaphrodite, 'pronouns'>; // string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment