Jomik
Jomik

Reputation: 559

Typescript: Infer type of generic object, within object

I have the following types:

export type SchemaEntry<A extends object, B> =
  | Validator<B>
  | ((obj: A) => Validator<B>);
export type Schema<A extends object> = { [k in keyof A]: SchemaEntry<A, A[k]> };

And a function that uses them:

function foo<A extends object>(f: Schema<A>): A {
  return undefined as any;
}

My issue is that when I call the function:

const a = foo({
  b: new Validator<number>(),
  c: (o) => new Validator<number>()
});

o's type will in this case be any rather than my expected {b: number, c: number}. a does however receive the correct type, {b: number, c: number}.

Is there a way that I can help typescript infer the type on my anonymous function?

Upvotes: 1

Views: 1151

Answers (1)

casieber
casieber

Reputation: 7542

The type inference flows from the parameter value to the function rather than the other way around. foo sees that the parameter you are passing in is applicable to the parameter constraints and thus allows it, but it's not going to retroactively type the untyped object for you.

Consider if you had written:

const input = {
  b: new Validator<number>(),
  c: (o) => new Validator<number>()
};

const a = foo(input);

After foo is called, you would not expect the type of input to be changed.

If you want to help typescript understand the type of o you will need to help it understand the strict type of the input object you are creating by typing it directly.

Doing so would also enable you to not explicitly type the Validator generics of <number> since that should also be inferred from the overall type.

I'd recommend trying to write the code I have written above, but give it a specific type const input: <Your_Type_Here> = {...

Upvotes: 1

Related Questions