Skip to content

Instantly share code, notes, and snippets.

@vimanvh
Last active July 21, 2022 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vimanvh/cef990e8dcac2b66baecfffde6ab05b0 to your computer and use it in GitHub Desktop.
Save vimanvh/cef990e8dcac2b66baecfffde6ab05b0 to your computer and use it in GitHub Desktop.
customized-fields.ts
// custom type names
type CustomType = "type1" | "type2";
// mapping from custom type names to TypeScript types
type TypeOf<T extends CustomType> =
T extends "type1" ? string
: T extends "type2" ? number
: never;
// generic Options type parametrized by custom types
type Options<T extends CustomType> = {
type: T;
value: TypeOf<T>;
}
// field names associated with custom type names
type Fields = {
[k: string]: CustomType
}
// field configuration as keys associated with Options
type Configuration<F extends Fields> = {
[P in keyof F]: F[P] extends CustomType ? Options<F[P]> : never;
}
// Result with keys typed by configuration
type Result<F extends Fields> = {
[P in keyof F]: F[P] extends infer T extends CustomType ? TypeOf<T> : never;
}
// function parametrized by configuration returning typed result
function foo<F extends Fields>(f: Configuration<F>) {
return {} as Result<F>;
}
// example
const test = foo({
field_a: {
type: "type1",
// type "string" is determined by "type1" name
value: "test string"
},
field_b: {
type: "type2",
// type "number" is determined by "type2" name
value: 10
}
})
// we have functional intellisense for the entire configuration as
// well as for the result
// type "string"
const fa_val = test.field_a;
// type "number"
const fb_val = test.field_b;
export { test };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment