1

Simple example of what I am trying to do:

const simpleExample = <T>(v: T = 'cat') => {
  return v;
};

Error:

Type 'string' is not assignable to type 'T'.
  'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.ts(2322)

The inference will work if I don't try to have a default parameter, so maybe the options is to wrap it in something that does the defaulting.. I don't understand why this doesn't work..




My actual code:

I want each of these Shape, Z, and Output to be infered from arguments and it works if I don't supply the default arg...

const createHooks = <
  Shape extends z.ZodRawShape,
  Z extends z.ZodObject<Shape, 'strict'>,
  Output extends z.ZodTypeAny
>(
  schema: Z,
  effect: (s: Z) => z.ZodEffects<Z, Output> = (s: Z) => s.transform((i) => i)
) => <Source, FProps extends { [k: string]: Record<string, any> }>({
  name,
  getInstanceKey,
  load,
  fieldProps,
}: {
  name: string;
  getInstanceKey: (s: Source) => string;
  load: (s: Source) => Z['_input'];
  fieldProps: FProps;
}) => {
 // ...
 return { }
}

Gets the error:

'Output' could be instantiated with an arbitrary type which could be unrelated to '{ [k in keyof addQuestionMarks<{ [k in keyof Shape]: Shape[k]["_output"]; }>]: addQuestionMarks<{ [k in keyof Shape]: Shape[k]["_output"]; }>[k]; }'

Which is frustrating, because I want any 'arbitrary type' to cause an error.

1 Answer 1

1

The problem is that your function could be called like simpleExample<number>(), in which case it promises to return a function of type (i: string) => number but does not. You can solve this by declaring two overload signatures: one with the type parameter, and one which will use the default argument with no type parameter.

function simpleExample<T>(f: (i: string) => T): (i: string) => T;
function simpleExample(): (i: string) => string;
function simpleExample(f = (i: string) => i) {
  return f;
};

Playground Link

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

3 Comments

Okay, this makes sense for the first part of my question, but I use the type parameter extensively in my function body and I don't want to explicitly set the return type, because it is complicated.. I know this is a very specific so maybe out of luck on SO I could imagine typescript just error simpleExample<number>() but what can you do..
I seem to be able to use type S = typeof schema; in my function scope, still investigating
I'll accept this answer if there are no more thoughts that arrive

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.