Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using TypeScript, is there a way to define an object of which each key is the same type, while preserving the information of which keys are used?

I have a type for a "helper" function which receives a context object as first parameter:

type helper = ((ctx: Context, ...params: any[]) => any);

Then I want to create an object of which each value is of the helper type:

const lib = {
  path: (ctx) => ctx.getPath(),
  array: (ctx, ...params) => new MyArray(ctx, params),
};

Is there a way to define the type of lib in this example so that each contained function already knows its of the helper type and doesn’t need to define the type of ctx over and over? So far, I know you can declare it like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const lib: {[key: string]: helper} = {
  path: (ctx) => ctx.getPath(),
  array: (ctx, ...params) => new MyArray(ctx, params),
};

But then the types would lose the information of lib containing the keys "path" or "array" since it can contain any key. Another alternative would be to define the type of every function like so:

const lib = {
  path: (ctx: Context) => ctx.getPath(),
  array: (ctx: Context, ...params: any[]) => new MyArray(ctx, params),
};

But that feels inefficient since we already know that all values of the lib object are of the same type. Is there a way to declare its type and get the best of both alternatives?

>Solution :

You’re looking for the new satisfies operator:

const lib = {
    path: (ctx) => ctx.getPath(),
    array: (ctx, ...params) => new MyArray(ctx, params),
} satisfies Record<string, Helper>;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Playground link

satisfies asserts that the left-hand type satisfies the requirements of the right-hand type without broadening the left-hand type. Here it allows TypeScript to infer the types of the function parameters, without broadening the type of lib such that you don’t have specific path and array property names anymore:

TypeScript playground showing lib. with the code suggestions path and array


Side note: In the above and linked playground I’ve capitalized Helper because it’s the standard convention for non-primitive types to start with a capital letter.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading