Есть несколько способов решения. Вы можете просто удалить встроенный typedef для result
const choose = <T, U>(
collection: T[],
selector: (elem: T) => U
): NonNullable<U>[] => {
const result = [];
for (const element of collection) {
const value = selector(element);
if (value !== undefined && value !== null) {
result.push(value); // this works
}
}
return result;
};
. Учитывая, что вы переносите это из F #, лучшим решением для вас может быть включение строгих нулевых проверок в ваш tsconfig. json, чтобы хотя вам не нужно явно указывать NonNullable
во-первых.
//with "strictNullChecks": true in your tsconfig.json
const choose = <T, U>(
collection: T[],
selector: (elem: T) => U
): U[] => {
const result = [];
for (const element of collection) {
const value = selector(element);
if (value !== undefined && value !== null) {
result.push(value);
//result.push(undefined); //can't do this and also return result
}
}
return result;
};
Если вы нажали undefined
на result
и попытались вернуть result
, компилятор пожаловался бы, что Тип результата функции должен быть U | undefined
Вы можете также принять концепцию неизменности с чем-то вроде этого.
const choose = <T, U>(collection: T[], selector: (elem: T) => U): U[] =>
collection.reduce((p, c) => {
const value = selector(c);
return value ? [...p, value] : p;
}, []);
В любом случае, я бы предложил включить strictNullChecks, если вы заинтересованы в работе с эффектом undefined (возможно, Option, как бы вы это ни называли)
По комментариям
Ожидается, что функция селектора вернет значение null или неопределенное значение.
В этом случае я бы предложил вызвать это в подпись функции
const choose = <T, U>(collection: T[], selector: (elem: T) => U | undefined): U[] => {
const result = [];
for (const element of collection) {
const value = selector(element);
if (value) result.push(value);
}
return result;
};