Skip to content
Learn Netverks
0

Setting parameters from a parameter function's mapped parameters with type safety in Typescript

asked 9 hours ago by @qa-fejjej5qg3wae9qygq9s 0 rep · 53 views

typescript

Suppose I have a function:

function doSomething(objA : MyObject,objB : MyOtherObject)

I also want to be able access MyObject by ID
In order to do this, I have a wrapper function that will apply a function to each parameter to turn the ID into the object:

function doSomethingWithID(do_something_function : (...args : unknown[]), ...parsers){
    return (...args) => {
        const true_args = [];
        for (let i = 0; i < args.length; i++){
            true_args.push(parsers[i](a));
        }
        do_something_function(...true_args);
    }
}

How should I type parsers ? Ideally it would be typed such that an error is given if a parser is missing or is of the wrong type.

Since Typescript 3.1 mapped tuples return as tuples, so I can get close with this:

type IDParser<Idable> = (
  parameter: Idable | string,
) => Idable;
type IDParsers<IdableParameters> = {
    [K in keyof IdableParameters]: IDParser<IdableParameters[K]>;
  }
function doSomethingWithID(
  do_something_function: (...args: any[]),
  ...parsers: IDParsers<Parameters<typeof do_something_function>>
){ /* Parse Ids then do something */}

But that doesn't give an error when an incorrectly typed parser is added as an argument.

Is there a better way to do this?

Comments on this question (0)

Use comments to ask for clarification — answers go in the answer box below.

Log in to comment on this question.

3 answers

0

Turns out it does work if you don't use Parameters and instead use generic types:

type IDParser<Idable> = (
  parameter: Idable | string,
) => Idable;
type IDParsers<IdableParamaters> = {
    [K in keyof IdableParamaters]: IDParser<IdableParamaters[K]>;
  }
function doSomethingWithID<Arguments extends unknown[] = unknown[]>(
  do_something_function: (...args: Arguments),
  ...parsers: IDParsers<Arguments>
){ /* Parse Ids then do something */}

This successfully gives an error if an invalid parser is used. Hooray!

Riley Morris · 0 rep · 9 hours ago

0

My apologies - I thought I was asking a best practice question largely because I thought what I was trying to do was impossible and that I was in the weeds with the type system for no reason. I thought I was asking about how people worked around a limitation.
Thank you for taking the time to help!

In the future I will be more careful with my labeling, and will get a playground running before I submit a question.
But yes, you have described exactly what I was trying to do. I think really what I've learned here is that it's best practice not to use Parameters outside of type definitions, because it doesn't resolve to the actual types involved.
Thank you again!

Reese Kim · 0 rep · 9 hours ago

0

Are you trying to ask an opinion-based "best-practices" question or are you just troubleshooting/debugging some code? If you're doing the latter then you've opened the wrong kind of question and what you'll get here is threaded "replies" which are combinations of comments (like this one) and possibly answers. You can't edit the type of question; all you can do is ask mods to delete and open a new regular troubleshooting/debugging question.

In either case please edit to provide a minimal reproducible example we can all use to test with and be on the same page. Stuff like MyObject and MyOtherObject and content_adding_function should either be removed or defined. Example code should be syntactically valid at least; check it with an IDE and fix any errors unrelated to your question (so (...args : unknown[]), needs to be fixed, for example).

EDIT: I think maybe, possibly, you're looking for

function doSomethingWithId<A extends any[], R>(
    doSomethingFn: (...args: A) => R,
    ...parsers: { [I in keyof A]: (id: string) => A[I] }
) {
    return (...args: { [I in keyof A]: string }): R =>
        doSomethingFn(...args.map((s, i) => parsers[i](s)) as A)
}

but I'd need a real example to test against (and note that I had to fix stuff in there you didn't ask about at all, and maybe I didn't do what you meant to do). See this playground link and let me know and please edit as needed to clarify.

Cameron Lopez · 0 rep · 9 hours ago

Your answer