typescript - 为什么在检查 null 和 undefined 后需要转换 `as NonNullable<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 语句中告诉某些内容不能为空或未定义。

最佳答案

有几种方法可以解决。您可以简单地删除 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 中包含严格的空检查,这样您就不必明确指定 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;
};

如果您按下 undefinedresult并试图返回 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 如果您有兴趣处理未定义的影响(也许,选项,无论您想怎么称呼它)

每条评论

The selector function is expected to return null or undefined.



在这种情况下,我建议在函数签名中调用它

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

关于typescript - 为什么在检查 null 和 undefined 后需要转换 `as NonNullable<T>`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61236978/

相关文章:

angular - typescript /TSLint : TSLint not recognizing root-relative imports via baseUrl

angular - angular2中的可投影节点是什么

typescript - 在惯用的 Typescript 中,我应该始终声明变量的类型,还是应该更多地依赖类型推断?

reactjs - React 16.2 <Fragment> 给出未捕获错误 : Element type is invalid

reactjs - 枚举值中的字符串连接

typescript - 防止 TypeScript 编译器退出批处理脚本

typescript - 停止 typescript-eslint/explicit-module-boundary-types 应用于不使用 Typescript 的 vue 组件

angularjs - tsconfig.json : using TypeScript in a team with Atom and VSCode?

javascript - MUI - React 无法识别 Datepicker 中 DOM 元素上的 `renderInput` Prop

javascript - 仅使用没有名称的方法签名声明类的接口(interface)