O TypeScript não consegue inferir tipo diferente de undefined através de filter(x => x !== undefined)
O seguinte código TypeScript (4.5.5) gera o erro abaixo:
interface Y {
prop: string;
}
interface O {
[key: string]: { x: number; y: Y | undefined };
}
function foo(o: O): Y[] {
return Object.keys(o)
.filter((key) => o[key].y !== undefined)
.map((key) => o[key].y);
}
Erro :
Type '(Y | undefined)[]' is not assignable to type 'Y[]'.
Type 'Y | undefined' is not assignable to type 'Y'.
Type 'undefined' is not assignable to type 'Y'.ts(2322)
Parece que o Typescript não consegue inferir o tipo a partir do filter().
Claro que eu posso "corrigir" isso assim:
.map((key) => data[key].error || ({} as Y))
or
function foo(o: O): (Y | undefined)[] { ... }
Eu teria pensado que o TS seria capaz de entender o filter(key => !!o[key].y)
Eu perdi alguma coisa?
Resposta #1
Vale a pena usar Object.values em vez de Object.keys:
interface Y {
prop: string;
}
interface O {
[key: string]: { x: number; y: Y | undefined };
}
const withY = (value: O[string]): value is O[string] & { y: Y } =>
value.y !== undefined
const getY = (value: O[string] & { y: Y }) => value.y
const foo = (o: O): Y[] =>
Object.values(o)
.filter(withY)
.map(getY);
Parque infantil
Além disso, eu adicionei o predicado withY que funciona como um typeguard.
Os callbacks filter e map são movidos para fora do escopo de foo. Dessa forma, você não precisa inicializar a mesma função arrow quando foo é chamado. Considere isso como uma micro otimização que torna o código mais legível
