You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular项目如何绕过tsc转译检测浏览器optional chaining支持

问题描述

在Angular应用中,需要检测客户端浏览器对optional chaining(ES2020特性)的原生支持情况,从而决定加载库的现代ES版本还是legacy兼容版本。

目前遇到的问题是:Angular编译器(本质是tsc的通用行为)会将所有代码转译为配置的目标ES版本(当前配置为ES6),导致用来检测optional chaining支持的代码被转译,无法在运行时正常完成检测:

export function isOpChainingSupported(): boolean {
  const opChainingChecker = {
    support: true
  };
  try {
    // 转译前代码:
    // return opChainingChecker?.support;
    //
    // 转译后变为
    return opChainingChecker === null || opChainingChecker === void 0 ? 
      void 0 :
      opChainingChecker.support;
  } catch {
    return false;
  }
}

尝试将这段检测代码放到普通JS文件中,开启TS配置的allowJs来无报错导入,但没有效果:tsc仍然会将该文件代码转译。

目前想到三个不太满意的解决方案:

  • 使用eval('constObj?.prop')实现,但多数资料表示该方案存在安全风险;
  • 将存放检测代码的普通JS文件作为静态资源,动态加载执行;
  • 单独为该检测函数封装一个ES工具库(目前的备选方案,但对于该需求来说过于冗余)。

请问有没有遗漏的更简单的实现方案?


解决方案

方案1:使用Function构造函数(推荐)

Function构造函数接收的字符串形式的代码不会被tsc转译,且相比eval安全很多——它的运行作用域为全局作用域,不会访问当前闭包的变量,只要代码字符串是固定的静态内容,完全不存在安全风险:

export function isOpChainingSupported(): boolean {
  try {
    const checker = new Function('return { support: true }?.support === true');
    return checker();
  } catch {
    return false;
  }
}

该方案代码简洁,不需要额外资源或配置,满足需求。

方案2:在index.html中内联检测代码

把检测逻辑直接写在index.html的内联script标签中,挂载到全局window对象上,tsc完全不会处理这段代码:

  1. 在index.html的head标签中添加:
<script>
  window.__OP_CHAINING_SUPPORTED__ = (function() {
    try {
      return { support: true }?.support === true;
    } catch {
      return false;
    }
  })();
</script>
  1. 在TS代码中添加全局类型声明,直接读取全局变量即可:
declare global {
  interface Window {
    __OP_CHAINING_SUPPORTED__: boolean;
  }
}

export function isOpChainingSupported(): boolean {
  return window.__OP_CHAINING_SUPPORTED__;
}

该方案性能更好,页面加载阶段就完成了检测,运行时直接读取结果即可。


内容的提问来源于stack exchange,提问作者Lincoln Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:36:02