Consider the following scenario where type definitions and function implementations are provided:
interface WithNumber {
foo: number;
}
interface WithString {
bar: string;
}
type MyType = WithNumber | WithString;
interface Parameter<C extends MyType = MyType> {
container: C
}
function isParameterWithNumberContainer(arg: Parameter): arg is Parameter<WithNumber> {
return typeof (arg.container as WithNumber).foo === "number";
}
function test(arg: Parameter<WithNumber | WithString>) {
if (isParameterWithNumberContainer(arg)) {
arg.container.foo;
return;
}
/*
* Error:
* Property 'bar' does not exist on type 'MyType'.
* Property 'bar' does not exist on type 'WithNumber'.
*/
arg.container.bar;
}
Why doesn't TypeScript narrow down the type of arg
below the if-block secured with a type guard? It seems clear that arg
can only be a Parameter<WithString>
. However, TypeScript still considers it as a
Parameter<WithNumber | WithString>
, leading to an error when trying to access arg.container.bar
.