Angular 8 Native Typescript 无崩溃,访问器简写

Posted

技术标签:

【中文标题】Angular 8 Native Typescript 无崩溃,访问器简写【英文标题】:Angular 8 Native Typescript crash-free, accessor shorthand 【发布时间】:2020-01-17 11:57:34 【问题描述】:

角度 8:

我曾经在打字稿方面用作简短的技巧:

object['accessor']['accessor']['accessor']

得到

object.accessor.accessor.accessor

如果其中一个孩子是空的,则不会冒引发错误的风险。

根据当今的 ECMA 脚本标准在 typescript 文件中执行此操作的最佳方法是什么?

编辑:

我找到了这个https://medium.com/inside-rimeto/optional-chaining-in-typescript-622c3121f99b

b/ 嵌套三元表达式似乎是最好的,但看起来很复杂

编辑 2:

没关系,这同样会导致应用程序崩溃(尽管在组件级别),并且无法挽回。

似乎较新的anguar规则更严格。他们只是没有提供替代方案。

【问题讨论】:

您链接的媒体帖子几乎列出了此问题的所有可能解决方法。该帖子中的内容是否不清楚,或者您只是在寻找更好的解决方案? (不存在 AFAIK) 更好的解决方案。角度 8 的最新变化甚至使这些建议也失败了。我获得的唯一成功是完全冗长if(object.accessor !== null && object.accessor !== undefined ) console.log(object.accessor.accessor.accessor) 当您必须重复许多无法迭代的对象和键时,这不太理想 欺骗Test for existence of nested javascript object key @HereticMonkey 我正在寻找一种速记,但递归函数可能已经为我节省了一些代码。我将返回对象而不是 true/false,但我需要立即使用该值 这个速记够了吗? (() => tryreturn object.accessor.accessor.accessorcatch(e)return default;)(); ... 可选链接还不够快:) 【参考方案1】:

您可以简单地执行以下操作

// Sample object

const object = 
    someKey: 'First Level Value',
    accessor: 
        someKey: 'Second Level Value',
        accessor: 
            someKey: 'Third Level Value',
            accessor: 'Accessor Value'
        
    
;

// Using ternary expression to do conditional validation check
// Usage --> condition to check ? 'Do this if condition is true' : 'Do this if condition is false'

const accessorValue = object ? // first (?) operator
    object.accessor ? // second (?) operator
        object.accessor.accessor ? // third (?) operator
            object.accessor.accessor ? // fourth (?) operator
                object.accessor.accessor.accessor :
                null : // to match the first (?) operator
            null : // to match the second (?) operator
        null : // to match the third (?) operator
    null; // to match the fourth (?) operator

console.log(accessorValue); // Accessor Value

【讨论】:

当访问器不存在并且组件的其余部分停止加载时,这会引发未定义的异常。 它可能会显示编译时 TypeScript 错误,但应该没有运行时错误。 不,我说的是对象不存在或不拥有该子对象时的运行时错误。 如果访问器不存在,会返回undefined,这是假的,所以它应该只是去三元的假边。 使用 typescript,您可以/应该为您的对象/模型编写一个接口类,以便在开发时检测可能的运行时错误。【参考方案2】:

我更喜欢布尔表达式的方法。

let object = 
  accessor: 
    accessor: 
      accessor: "test"
    
  


if (object
   && object.accessor
   && object.accessor.accessor
   && object.accessor.accessor.accessor) 
  console.log(object.accessor.accessor.accessor);
 else 
  console.log(null);

如果你不关心编译时错误检查,你可以做一些像这样奇怪的事情。我不会推荐它。

function tryGetValue(obj, propertiesPath) 
  if (!obj) 
    return null;
  

  if (!propertiesPath) 
    return obj;
  

  let current = obj;
  let properties = propertiesPath.split(".");
  for (let i = 0; i < properties.length; i++) 
    if (current[properties[i]] !== undefined) 
      current = current[properties[i]];
     else 
      current = null;
      break;
    
  

  if (current !== undefined) 
    return current;
   else 
    return null;
  


console.log(tryGetValue(object, "accessor.accessor.accessor"));

【讨论】:

如果对象未定义,则在没有相等条件的情况下测试对象将导致崩溃。我不知道这是否是一个有角度的事情,但是:if(object.accessor) = 崩溃if(object.accessor !== undefined &amp;&amp; object.accessor !== null) = 成功。打败我为什么会这样,但事实就是这样。【参考方案3】:

我喜欢在我的 Angular 项目中使用 Ramda's path function。

import * as R from 'ramda';

const leaf = R.path(['accessor', 'accessor', 'accessor'], object);

如果 child 为空(当 ramda 不在时),我一直在使用另一种避免崩溃的方法,来自 swifts .??? 运算符的灵感,如果 child 为空,则默认为某些东西。

您不需要花哨的功能,这个单班轮就可以做到防崩溃的技巧

const leaf = (((object || ).accessor || ).accessor || ).accessor;

实际操作:

const wrongObject =  accessor: null ;
const validObject =  
  accessor: 
    accessor: 
      accessor: 'your leaf value'
    
  
;

// crash proof, returning: undefined
const wrongLeaf = (((wrongObject || ).accessor || ).accessor || ).accessor
console.log(wrongLeaf);

// or even with fallback / default value
const defaultLeaf = (((wrongObject || ).accessor || ).accessor || ).accessor || 'default 123';
console.log(defaultLeaf);

const validLeaf = (((validObject || ).accessor || ).accessor || ).accessor
console.log(validLeaf);

【讨论】:

【参考方案4】:

armanozak 有一个名为 snq(Safe Navigation Query) 的 npm 包。非常简单且强大的解决方案。

你可以这样使用它

snq(() => object.accessor.accessor.accessor, anyDefaultValueIfYouLike);

如果你想知道它是如何工作的,这里是我从github repo复制的源代码

export default function snq<T = any>(callback: () => T, defaultValue?: T) 
  try 
    const result = callback();
    return typeof result === 'undefined' ? defaultValue : result;
   catch (err) 
    if (err instanceof TypeError) 
      return defaultValue;
    

    throw err;
  

【讨论】:

【参考方案5】:

你可以做这样的事情作为速记,这将允许类型流动,我想。

const value = (() => tryreturn object.accessor.accessor.accessorcatch(e)return yourDefault;)();

【讨论】:

真的在紧要关头。还剩 14 分钟。

以上是关于Angular 8 Native Typescript 无崩溃,访问器简写的主要内容,如果未能解决你的问题,请参考以下文章

typescri枚举enum

Ionic2 + Angular2 还是 React-native? [关闭]

Angular 2,iOS Safari 错误:eval@[native code]

带有nestjs的Angular-universal:错误:找不到模块'./drivers/node-mongodb-native/connection'

如何在 Angular 2.0 中使用 formControl 访问 Native HTML Input 元素

如何从 React ^0.14.8 & React-native ^0.24.1 升级到 React 15.0.2 和 React-native 0.26.3