0

We need to type the function, which requires a list of keys (strings) and produces object with the same keys where values are string | undefined when key starts with ? or otherwise just string.

export function useParams<T extends string>(
  expected: T[]
): { [key in T as NonOptional<T>]: string } {
  // ... our custom implementation
  return null as any;
}

type NonOptional<T extends string> = T extends `?${infer Inner}` ? Inner : T;

// Should produce type { a: string; b: string | undefined }
const result = useParams(['a', '?b']);

However, I'm not sure how to type the output.

1 Answer 1

1

You may write it iterating over tuple's keys:

export function useParams<T extends readonly string[]>(
  expected: T
): { [K in T[number] as NonOptional<K>]: string | OrUndefined<K> } {
  return null as any;
}

type NonOptional<T extends string> = T extends `?${infer Inner}` ? Inner : T;
type OrUndefined<T extends string> = T extends `?${string}` ? undefined : never

const result = useParams(['a', '?b'] as const);

playground link


Added section to address the problem described in comments:

I'm pretty sure developers will forgot to add as const and then it will stop working correctly.

To allow passing non-readonly tuples you may use variadic tuple types:

export function useParams<T extends string[]>(
  expected: [...T]
): { [K in T[number] as NonOptional<K>]: string | OrUndefined<K> } {
  return null as any;
}

type NonOptional<T extends string> = T extends `?${infer Inner}` ? Inner : T;
type OrUndefined<T extends string> = T extends `?${string}` ? undefined : never

const result = useParams(['a', '?b']);

playground link

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

1 Comment

Thanks! Looks good but unfortunately, I'm pretty sure developers will forgot to add as const and then it will stop working correctly. Any idea how to make it works without as const?

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.