Consider the following code:
type TestTuple = [
{ test: "foo" },
{
test: "bar";
other: 1;
}
];
type Foo<Prop extends string> = TestTuple extends Record<Prop, string>[]
? true
: false;
type X = Foo<"test">;
type Prop = "test";
type Y = TestTuple extends Record<Prop, string>[]
? true
: false;
// X is type false
const x: X = false;
// Y is type true
const y: Y = true;
Types Foo
and Y
are the exact same, except Foo
has a generic parameter Prop
, whereas Y
just uses a type alias called Prop
(the type alias isn't required, Y
could just be TestTuple extends Record<"test", string>[] ? true : false
but I wanted to make their declarations exactly the same). So, Foo<"test">
(which is aliased into the type X
) and Y
should have the same types, right? Apparently not. X
as type false
whereas Y
is type true
. Changing the other
property in TestTuple
to a string or removing the property altogether causes both X
and Y
to be true, which is the expected behavior.
So, my question is: why is this? Is this a bug in the compiler? If so, has an issue already been filed that I've been unable to find? Or, is this some weird way that generics are handled in typescript?
type What<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
. That type is eagerly reduced totype What<K extends string> = false
no matter what you put in forK
, even thoughWhat<"y">
should betrue
. link – Dwarfish{x: obj}
somehow affects the behavior. It seems that the mere presence of a generic causes the compiler to start acting weird. – Federico