Encountering a limitation of IntelliSense autosuggest has been noted in the issue microsoft/TypeScript#51047. Overloads differing by literal types appear to be inaccurately grouped together in completion lists until this issue is addressed. To work around it, you will need to accept the situation or refactor to avoid overloads.
One approach is to use generics instead of overloads. By creating a "mapping" interface that represents parameters as an object structure, you can achieve this:
interface ConfigMap {
event: {
view_product: { view_product_key: any };
update_cart: { update_cart_key: any };
};
}
With this type, a FooFn
should take a key of ConfigMap
as the first argument, delve into that property, have the next argument as a key of that property, and finally, the third argument should be the value at that nested key. You can define this using generics and indexed access types:
interface FooFn {
<K1 extends keyof ConfigMap, K2 extends keyof ConfigMap[K1]>(
method: K1, type: K2, config: ConfigMap[K1][K2]
): void
}
This creates a FooFn
with two generic type parameters: K1
for the method
argument restricted to keys of ConfigMap
, and K2
for the type
argument constrained to keys of ConfigMap[K1]
.
The config
parameter is of type ConfigMap[K1][K2]
, reflecting the property type when accessing the K1
property of ConfigMap
followed by the K2
property of ConfigMap[K1]
.
Although the behavior of accepted and rejected calls remains similar:
window.fooBar('event', 'view_product', { update_cart_key: 1 }) // error
window.fooBar('event', 'view_product', { view_product_key: 1 }) // okay
IntelliSense now provides more accurate completions:
window.fooBar('event', 'view_product', {});
suggestion: ^ view_product_key
When calling
window.fooBar('event', 'view_product',
, the compiler deduces
"event"
as
K1
and
"view_product"
as
K2
, making the type of
config
resolve to
{view_product_key: any}
, eliminating any reference to
update_cart_key
in the call signature.
You can experiment further with the code on the TypeScript Playground here.