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

为何TypeScript编译器无法检测Object.create(null)创建对象的缺失属性?

问题描述

以下是编写的代码:

'use strict';

type Bar = 'a' | 'b';
type FooIntermidiate = {
  [p in Bar]: string;
};
type Foo = Required<FooIntermidiate>;

console.log(getFoo());

function getFoo(): Foo {
  const rv = Object.create(null);
  //const rv = {  };
  rv.b = 'str';
  return rv;
}

期望TypeScript编译器(tsc)抛出返回值(类型为Foo)至少缺少a属性的错误,但实际并未抛出。若使用const rv = { };,则会抛出a和b属性均缺失的错误。疑问点:

  • 为何使用Object.create(null)时不会抛出错误?
  • 是否使用Required<>类型对此无影响?
原因解析

1. 两种对象创建方式的类型推断差异

  • 使用const rv = {}时,TypeScript会推断其类型为空对象类型{},后续给rv.b赋值后,类型会更新为{ b?: string }。此时返回该对象匹配Foo类型(要求a、b均为必填字符串),类型检查器能直接识别出属性缺失问题。
  • 使用const rv = Object.create(null)时,TypeScript推断其类型为无原型的可索引对象(近似{ [key: string]: any })。这种类型下,TypeScript认为对象可以添加任意属性,不会严格追踪已添加属性是否满足目标类型的必填要求,返回时会默认该对象"潜在包含所有必要属性",因此不会触发错误。

2. Required<>类型的作用限制

Required<>仅负责将目标类型的所有属性从可选转为必填,但无法改变TypeScript对不同对象创建方式的类型推断逻辑。无论是否使用Required<>,只要通过Object.create(null)创建对象,类型检查器都会因宽松的推断规则跳过属性缺失检查。

解决方法

若要让TypeScript严格检查Object.create(null)创建的对象是否符合Foo类型,可手动为rv指定类型:

const rv: Foo = Object.create(null);
rv.b = 'str'; // 此时会直接报错,提示缺少'a'属性

内容的提问来源于stack exchange,提问作者d.k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:52:47