首页 > 解决方案 > Typescript 在闭包中看不到参数验证

问题描述

在我的代码中

interface INode {
    id: number,
    label: string;
    parentId?: number; 
}

let nodes: null | INode[] = null;

nodes = [
    { id: 0, label: 'zero' },
    { id: 1, label: 'one', parentId: 0 },
    { id: 2, label: 'two', parentId: 0 },
    { id: 3, label: 'three', parentId: 1 },
    { id: 4, label: 'four', parentId: 3 },
]


function calcBreadcrumbs(nodes: null | INode[]) {
  if (nodes === null) return;

  const id = 33

  function _findNode(nodeId: number): void {
    const node: INode | undefined = nodes.find(n => n.id === id);
    if (node === undefined) {
      throw new Error(`calcBreadcrumbs. Node ${nodeId} not found`);
    }

    // some code

    if (node.parentId) _findNode(node.parentId);

    return;
  }

  _findNode(id);
}

沙箱 1 我检查if nodes === null。但是 TS 告诉我'对象可能是'null'。(2531)'如果你将节点传递给 _findNode 函数,那么 TS 不会发誓

function _findNode(nodes: INode[], nodeId: number): void {...}

沙盒 2 为什么会这样?如何解决这个问题?

标签: typescript

解决方案


这是因为在第一个示例中nodes,内部函数的类型仍然是null | INode[]并且它可能是null. 例如,它可以null在调用之前设置为_findNode(id);

一种可能的解决方案是将参数分配给另一个变量:

function calcBreadcrumbs(nodes: null | INode[]) {
  if (nodes === null) return;

  const guardedNodes = nodes; // guardedNodes is INode[]
  const id = 33

  function _findNode(nodeId: number): void {
    const node: INode | undefined = guardedNodes.find(n => n.id === id);
    // ...

    return;
  }

  _findNode(id);
}

操场


另一种选择是使用非空断言运算符

function calcBreadcrumbs(nodes: null | INode[]) {
  if (nodes === null) return;

  const id = 33

  function _findNode(nodeId: number): void {
    const node: INode | undefined = nodes!.find(n => n.id === id);
    // ...

    return;
  }

  _findNode(id);
}

操场

该操作x!产生类型为xwithnullundefinedexclude 的值。仅当您绝对确定该值已定义时才使用此选项。


推荐阅读