Reputation: 145
Is it possible get dynamic type depended on value of key dataIndex
(create dynamic discriminating union type with generic)?
type EntityList<EntityType> = {
dataIndex: keyof EntityType;
render?: (value: any /*bad*/, record: EntityType) => void;
}[]
// Some dynamic type
type Issue = {
id: number;
name: string;
description?: string;
flag?: boolean;
};
const arr:EntityList<Issue> = [
{ dataIndex: 'id', render: (id, record) => {
console.log({id, record}); } // id should be number
},
{ dataIndex: 'name', render: (name, record) => {
console.log({name, record}); } // name should be string
},
{ dataIndex: 'flag', render: (flag, record) => {
console.log({flag, record}); } // flag should be boolean
},
]
answer:
type EntityList<EntityType> = {
[K in keyof EntityType]: {
dataIndex: K,
render?: (value: EntityType[K], record: EntityType) => void
}
}[keyof EntityType][]
thanks @Tobias S.
Upvotes: 2
Views: 234
Reputation: 23925
This should work for you:
type EntityList<EntityType> = {
[K in keyof Issue]: {
dataIndex: K,
render?: (value: Issue[K], record: EntityType) => void
}
}[keyof Issue][]
We create a mapped type and iterate over all keys of Issue
. Afterwards we convert this type to a union of all possible combinations with [keyof Issue]
.
This does not quite match your requirement since you wanted flag
to be of type boolean
. But since the flag
property is optional the type is boolean | undefined
. To fix this, add -?
:
type EntityList<EntityType> = {
[K in keyof Issue]-?: {
dataIndex: K,
render?: (value: Issue[K], record: EntityType) => void
}
}[keyof Issue][]
Upvotes: 2