Search code examples
typescripttypescript-types

TS - types - omit field in parameter object in function while keeping types


I have a type that omits specified fields in functions parameter object like this:

type OmitFields<F, K extends string> = F extends (props: infer P) => infer R ? (props: Omit<P, K>) => R : never;

And use it like:

type Omitted = OmitFields<typeof functionWithObjectParam, 'first' | 'second'>

How can I make type parameter K be aware of type that props object gets inferred as, and restrict correct strings to its keys?


Solution

  • I think you want something like:

    type OmitFields<
        F extends (props: any) => any,
        K extends keyof Parameters<F>[0],
    > = (props: Omit<Parameters<F>[0], K>) => ReturnType<F>
    

    Here F is constrained to be a function that takes one argument. And K is constrained to the keys of that argument.

    Then you can reconstruct the function type without any fancy infer stuff.

    This seems to do what you want:

    function functionWithObjectParam(props: { a: number, b: number }) {}
    
    type Omitted = OmitFields<typeof functionWithObjectParam, 'b'> // ok
    type OmittedBad = OmitFields<typeof functionWithObjectParam, 'bad'> // Type '"bad"' does not satisfy the constraint '"b" | "a"'.(2344)
    
    declare const fn: Omitted
    
    fn({ a: 1 }) // ok
    
    fn({ a: 1, b: 2 })
    // Argument of type '{ a: number; b: number; }' is not assignable to parameter of type 'Omit<{ a: number; b: number; }, "b">'.
    //   Object literal may only specify known properties, and 'b' does not exist in type 'Omit<{ a: number; b: number; }, "b">'.
    

    Playground