Я пытаюсь отфильтровать данные по свойству code
, значение которого не равно 'd'
. JS-код в порядке. Я ожидаю, что свойство code
в отфильтрованном типе данных будет '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')
Получил ошибку:
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 не будет использовать v.code !== 'd'
для изменения типа элемента в массиве.
Вы можете создать пользовательскую защиту типа, чтобы сузить тип элемента, но в основном вы берете на себя управление и сообщаете компилятору, что выполняемая вами проверка сужает тип элемента, на самом деле не обеспечивается, чтобы ваша проверка сужала тип правильно.
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')
@slideshowp2 Нет
Есть ли способ позволить TSC сузить тип вместо предиката типа разработчиком?