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)
CodePudding user response:
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')