In search of a way to create a function with statically typed input object keys based on certain key values, I have created a TypeScript playground containing a failing test. Click the link below to access the playground:
export type Input<$Method extends URL | 'memory'> = {
method: $Method
} & ($Method extends URL ? { headers?: HeadersInit } : {})
declare const foo: <$Input extends Input<URL | 'memory'>>(input:$Input) => $Input
foo({ method: new URL('http://abc'), headers: {} }) // OK
foo({ method: new URL('http://abc') }) // OK
foo({ method: 'memory' }) // OK
// @ts-expect-error headers should be disallowed
foo({ method: 'memory', headers:{} })
// ^^^^^^^^^^ -- should error
The challenge remains unresolved where headers
is expected only when method
equals URL
. I am inquiring about alternative methods to achieve this.
An additional observation shows that the inferred type is accessible at the output position (return).
-- edit
I discovered one solution utilizing an Exact type helper, but I am curious if there's a simpler approach available. Access the provided link here.