Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use property to filter data while filtering the union type of the property

I am trying to filter the data by code property that the value is not equal to 'd'. JS code is fine. I expect code property in the filtered data type is 'a' | 'b' | 'c'.

type Code = 'a' | 'b' | 'c' | 'd';
interface Data {
  code: Code;
}

const data: Data[] = [{ code: 'a' }, { code: 'b' }, { code: 'c' }, { code: 'd' }]

interface Filtered {
  code: Exclude<Code, 'd'>;
}
const filtered: Filtered[] = data.filter(v => v.code !== 'd')

Got error:

Type 'Data[]' is not assignable to type 'Filtered[]'.
  Type 'Data' is not assignable to type 'Filtered'.
    Types of property 'code' are incompatible.
      Type 'Code' is not assignable to type '"a" | "b" | "c"'.
        Type '"d"' is not assignable to type '"a" | "b" | "c"'.(2322)

TypeScript Playground

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Typescript will not use v.code !== 'd' to change the type of the item in the array.

You can create a custom type guard to narrow the type of the item, but this is basically you taking control and telling the compiler that that check you perform will narrow the item type, it is not actually enforced that your check narrows the type correctly.

const filtered: Filtered[] = data.filter((v): v is Filtered => v.code !== 'd')

// v is Filtered is not checked
const filteredBad: Filtered[] = data.filter((v): v is Filtered => v.code !== 'a')

Playground Link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading