Given type
type X = {
a: {
b: {
c: string;
};
};
};
I would expect
type Y = {
[k in keyof X]: {
[j in keyof X[k]]: X[k][j]['c'];
};
};
to give me
{
a: {
b: string;
};
};
However, I get error ts2536: "Type 'c' cannot be used to index type 'X[k][j]'
here. But that is wrong, isn't it?
So why does the error happen and what could I do to fix it?
CodePudding user response:
The expression X[k][j]
seems to be too complicated for TypeScript to remember all the relations between X
, k
and j
. So it does not know that X[k][j]
must have a property c
.
We can help TypeScript accept this by adding an addtional check before indexing X
.
type Y = {
[k in keyof X]: {
[j in keyof X[k]]: X[k][j] extends { c: any } ? X[k][j]['c'] : never;
};
};
This extra check will always be true but it tells TypeScript that X[k][j]
must have a property c
in the true branch.
This is a bit shorter but also has the same effect:
type Y = {
[k in keyof X]: {
[j in keyof X[k]]: (X[k][j] & { c: any })['c'];
};
};