1

I would like to create a function that takes some partial props to populate a type, and returns another function, which in turn accepts exactly the remainging props to create an object of the type.

declare function creator<T extends U>(defaults: U) =>
  (fields: Pick<T, Exclude<keyof U, keyof T>>) => T

so that I can do:

type A = { a: number, b: string };
const make = creator<A>({ a: 1 }); // ({ b: string }) => A
  1. I don't know how to let creator only accept T at call-time, but declare it extending U and infer U.
  2. I don't know why I cannot "construct" T from U and Pick<T, Exclude<keyof U, keyof T>> with generics. It is possible with types directly:
type T = { a: number; b: string };
type A = { a: number };
type T1 = A & Pick<T, Exclude<keyof A, keyof T>>;
const t1: T = { a: 1, b: "b" };
const t2: T1 = t1;

1 Answer 1

1

You can't have partial argument inference in typescript. This means you can't specify T and infer U in the same call. You can do it using function currying.

type Omit<T, K extends PropertyKey> = Pick<T, Exclude<keyof T, K>> // not needed in 3.5
function creator<T>() {
    return function <K extends keyof T>(defaults: Pick<T, K>) {
        return function (values: Omit<T, K>) :T {
            return Object.assign(values, defaults) as unknown as T
        }       
    }
}

type A = { a: number, b: string };
const make = creator<A>()({ a: 1 }); // ({ b: string }) => A
make({ b: "" })

Also inside the function where T is still not known typescript will not be able to do a lot of reasoning about what Omit<T, K> is. This is why assigning the result of Object. assign fails inside the function, while in similar conditions outside a generic function (where all type are known) it would succeed. Using a type assertion is the only way to get things to work.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, creator<A>()({ a: 1 }); is fine.

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.