1

How to omit prop type from generic function?

declare function func1<T extends {...}>(params: {age: number, something: T, ...more}): string

declare function func2<FunctionType extends (...args: any) => any>(cb: FunctionType): FunctionType
const newFunction = func2(func1)  // returns same type as func1
newFunction<{...}>({something: {...}, age: ...}) // is valid, but age should not be valid

in func2 how to remove property age from first argument of FunctionType?

I tried:

declare function func2<FunctionType extends (...args: any) => any>(cb: FunctionType): 
(params: Omit<Parameters<FunctionType>[0], 'age'>) => ReturnType<FunctionType>

const newFunction = func2(func1)  // This returns the new function type without age, but also without generics
newFunction<{...}>({...})   // the generic is no longer valid, bit is should be

This way I can remove the property age, but the return type is no longer generic. How I can keep it generic and omit the age from the first argument?

1 Answer 1

2

Not sure what you need that generic for since you don't seem to use it, but this should do:

declare function func2<P extends {}, R>(f: (params: P) => R)
   : (params: Omit<P, 'age'>) => R
Sign up to request clarification or add additional context in comments.

4 Comments

It is just an example, I have more generics in my real situation... anyway... I can't understand how this works. Your return type is (params: Omit<P, 'age'>) => R, and there are no generics in that type, but actually it accepts generics. How?
ReturnType and Parameters have the limitations you identified regarding generics, so instead of inferring the entire callback, which has generics, and loosing those generics, I inferred the parameter params and the return type as P and R directly. And this, TS can wire correctly.
I have to be able to add property to the returned function (just like an object) like this: const cb = () => {...}; cb.something = ... But this does not work. Do you have any solution for this (except cb.prototype.something = ...)? Since I return (params: Omit<P, 'age'>) => R, it does not allow me to add properties to the function
Theoretically you could return ((params: Omit<P, "age">) => R) & { foo: bar } but it doesn't seem to work unless you set the constraint of P to be {age: number, something: unknown, ...more} to match func1. I don't know why TS is restricting the variance as soon as we add that intersection, especially given it should only affect the return type. It would make for a good SO question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.