UPDATE: As of the release on 2019-05-30, TypeScript 3.5 has brought in smarter union type checking. However, this update does not address the specific issue mentioned here. This is likely due to the usage of a generic type K
instead of a union of defined concrete types. Therefore, the solution provided below remains unchanged for now.
It seems that the core problem lies in how TypeScript handles unions, which may be different from what you would expect. For instance, consider the following scenario:
declare const innerUnion: { foo: string | number };
const outerUnion: { foo: string } | { foo: number } = iU; // error
In this case, TypeScript does not automatically narrow down the type of outerUnion
based on the type of
innerUnion</code. The decision not to do so appears to be practical, as such reduction could lead to incorrect outcomes when there are additional properties involved:</p>
<pre><code>declare const iU: { foo: string | number, bar: string | number };
const oU: { foo: string, bar: string } | { foo: number, bar: string } = iU; // error
The above error serves a purpose, considering that iU
might be something like { foo: 0, bar: '' }
.
According to TypeScript, K
can only be of type
'henk' | 'piet'</code, leading to the output of the function being either <code>Wrapper<'henk'>
or
Wrapper<'piet'>
. Since TypeScript doesn't perform such union reduction, it flags this as an error.
So, why does the return value appear as
Wrapper<'henk'> | Wrapper<'piet'></code? It's because indexing into objects using a union of keys results in a union of property values within that object.</p>
<p>A possible solution to your issue lies in utilizing a <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" rel="nofollow noreferrer">lookup type</a> to represent the indexing operation:</p>
<pre><code>function getWrapper<K extends keyof Wrappers>(k: K): Wrappers[K] {
return wrappers[k]; // this should work
}
This implementation should align with your requirements. Best of luck!