简体   繁体   中英

How to get distinct values from array in Typescript

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][] ).


TypeScript Playground link

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM