【问题标题】:Typescript does not see parameter validation in closureTypescript 在闭包中看不到参数验证
【发布时间】:2020-10-13 12:00:49
【问题描述】:

在我的代码中

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

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

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

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

【问题讨论】:

    标签: typescript


    【解决方案1】:

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

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

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

    Playground


    另一种选择是使用non-null assertion operator

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

    Playground

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

    【讨论】:

    猜你喜欢
    • 2018-07-15
    • 1970-01-01
    • 2012-02-11
    • 2020-12-20
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多