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

TypeScript严格模式下,如何检查表达式作为对象属性名的undefined?

TypeScript 表达式属性访问时的类型收窄问题解决方法

报错代码示例

type Props = 'foo' | 'bar';
type ParRec = Partial<Record<Props, string>>;

function doSomething (item: ParRec) {
  const props: Props[] = ['foo', 'bar'];
  return props.map((prop) => {
    if(item[prop]) {
      const result: string = item[prop]; // 此处抛出ts(2322)错误
      return { result };
    }
    return {};
  });
} 

TypeScript在此处抛出**ts(2322)**错误,提示string | undefined 不能赋值给类型 string。尽管通过if(item[prop])做了非空判断,但由于使用表达式作为属性名,TypeScript无法正确收窄类型。

无报错代码对比

function doSomething (item: ParRec) {
  const props: Props[] = ['foo', 'bar'];
  return props.map((prop) => {
    if(item.foo) { // 使用item['foo']也可正常运行
      const result: string = item.foo;
      return { result };
    }
    return {};
  });
} 

直接使用明确的属性名(无论点语法还是字符串字面量索引)时,TypeScript能正确识别条件判断后的类型,不会报错。

严格模式下的解决方法

以下方法适用于TypeScript 4.8.4严格模式:

  • 暂存属性值到局部变量
    将item[prop]先存入局部变量,TypeScript会跟踪该变量的类型,条件判断后自动收窄:

    function doSomething (item: ParRec) {
      const props: Props[] = ['foo', 'bar'];
      return props.map((prop) => {
        const val = item[prop];
        if(val) {
          const result: string = val;
          return { result };
        }
        return {};
      });
    }
    
  • 使用非空断言
    通过!断言值不为undefined,注意需确保逻辑上该值确实不会为undefined,避免运行时错误:

    function doSomething (item: ParRec) {
      const props: Props[] = ['foo', 'bar'];
      return props.map((prop) => {
        if(item[prop]) {
          const result: string = item[prop]!;
          return { result };
        }
        return {};
      });
    }
    
  • 自定义类型守卫函数
    编写类型守卫来明确告知TypeScript,当条件满足时属性值已定义:

    function hasDefinedProp<T, K extends keyof T>(obj: T, key: K): obj is T & { [P in K]-?: T[P] } {
      return obj[key] !== undefined;
    }
    
    function doSomething (item: ParRec) {
      const props: Props[] = ['foo', 'bar'];
      return props.map((prop) => {
        if(hasDefinedProp(item, prop)) {
          const result: string = item[prop];
          return { result };
        }
        return {};
      });
    }
    
  • 空值合并兜底
    使用??为可能的undefined值提供默认值,确保类型始终为string:

    function doSomething (item: ParRec) {
      const props: Props[] = ['foo', 'bar'];
      return props.map((prop) => {
        const result = item[prop] ?? '';
        if(result) {
          return { result };
        }
        return {};
      });
    }
    

内容的提问来源于stack exchange,提问作者Neil S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:00:47