为什么在检查空值<T>和未定义值后需要将"不可空"转换为不可空?

  • 本文关键字:转换 空值 未定义 typescript
  • 更新时间 :
  • 英文 :

// 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;
};

最新更新