I am trying to make well typed function for getting only distinct values of object's property in array. So it works like that
type Employee = { work: WorkEnum; name: string };
const arg1: Employee[] = [{ name: "kornad", work: WorkEnum.Doctor}, { name: "Adam", work: WorkEnum.FrontEndDeveloper}]
const result1: WorkEnum[] = getDistinct(arg1, 'work')
const result1: string[] = getDistinct(arg1, 'name')
so function needs to detect possible keys for seconds argument (that I've managed to do) and type of the value (I don't know how to do this one)
Here is my function
type ArrayObject<V> = {
[key: string]: V;
};
function getDistinct<V, T extends ArrayObject<V>>(
data: T[],
property: keyof T
): V[] {
const allValues = data.reduce((values: V[], current) => {
if (current[property]) {
values.push(current[property]);
}
return values;
}, []);
return [...new Set(allValues)];
}
const arrayOfData: { xxx: string; qwe: string | number }[] = [
{ xxx: 'asd', qwe: 43 },
{ xxx: 'asd', qwe: 'dsadas' },
];
const res = getDistinct(arrayOfData, 'xxx'); // res: unknown[], why not string[] ??????????
So Typescript cannot figure it out that res
should be string[]
instead of this I am getting here unknown[]
. How can I fix it?
As far as I can tell, the ArrayObject
definition and function return type are not correct.
This will work:
function getDistinct<T, K extends keyof T>(data: T[], property: K): T[K][] {
const allValues = data.reduce((values: T[K][], current) => {
if (current[property]) {
values.push(current[property]);
}
return values;
}, []);
return [...new Set(allValues)];
}
const arrayOfData: { xxx: string; qwe: string | number }[] = [
{ xxx: 'asd', qwe: 43 },
{ xxx: 'asd', qwe: 'dsadas' },
];
const res1 = getDistinct(arrayOfData, 'xxx'); // string[]
const res2 = getDistinct(arrayOfData, 'qwe'); // (string | number)[]
The important part is to define your property as a keyof T
, and the return type as the type associated with that property ( T[K]
), or in this case, an array of that type ( T[K][]
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.