I think it is not possible to do this with arrays (at least not in a way simple) because the compiler has no way of knowing the type of the element associated with a specific key for each element of the array. He would form a union with all possible types.
But it’s possible to make a structure out of objects. Something like this:
export interface IUser {
userId: number;
profile: {
profileId: number;
};
}
const columns: ColumnDefinitionType<IUser> = {
userId: {
header: 'ID do usuário',
width: 50
},
profile: {
subColumns: {
profileId: {
header: 'ID do perfil',
width: 50
}
}
}
};
Note that I have removed some fields to simplify the example.
It is a "recursive" structure. And precisely because of this, we need to create a recursive type for the case of objects nested to the main object. For this, you can use conditional types.
Behold:
export type BareColumn = {
header: string;
width: number;
};
export type ColumnDefinitionType<T> = {
[K in keyof T]: T[K] extends object
? { subColumns: ColumnDefinitionType<T[K]> } // Note que este tipo é recursivo para objetos.
: BareColumn;
};
Basically, you have a Mapped type that maps each property of the object T
for a new type. This new type is determined through a conditional type, so that:
- If the type of the current element is
object
(any primitive value), use an object that calls again the type ColumnDefinitionType
, passing the current object (which creates a recursive "structure").
- Otherwise, it is inferred that it is a primitive type (no
object
) and use the type BareColumn
(which contains simple information for a column without "children").
Thus, instead of having an array with information from each column, one has an object, in which the keys represent one’s own key
(that before was a property of each element of the array).
I don’t think it will be such a big limitation, but that is my assumption. Maybe this will serve as a way.
I left the complete example on Typescript playground.
This is because
role
is not a key toIUser
. How would thekey
?"profile.role"
?– Luiz Felipe
Exactly Luiz, he does not accept because it is not Iuser key, so I need to know if there is any way to adjust my Columndefinitiontype to accept the keys of nested objects. Either by going directly 'role' or as you mentioned 'profile.scroll'.
– Cristian Augusto