// This is an implementation of https://msdn.microsoft.com/visualfsharpdocs/conceptual/seq.choose%5b%27t%2c%27u%5d-function-%5bfsharp%5d
const choose = <T, U>(
collection: T[],
selector: (elem: T) => U
): NonNullable<U>[] => {
const result: NonNullable<U>[] = [];
for (const element of collection) {
const value = selector(element);
if (value !== undefined && value !== null) {
// result.push(value); TypeScript complains that U is not convertible to NonNullable<U>
result.push(value as NonNullable<U>); // this works
}
}
return result;
};
为什么我需要演员阵容,有没有办法打字这样我就不需要了?TypeScript通常能够在检查这些情况的if语句中判断某些内容不能为null或未定义。
有几种方法可以解决。您可以简单地删除result
的内联typedef
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中包含严格的null检查,这样您就不必首先明确指定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
每条评论
选择器函数应返回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;
};