【问题标题】:Why does index signature of the object type accept an object with no properties?为什么对象类型的索引签名接受没有属性的对象?
【发布时间】:2021-10-15 21:37:29
【问题描述】:

我有一个字典接口,我希望索引类型为字符串,值为字符串类型。

interface One {
 [key: string]: string;
}

如果我将此类型注释为一个包含没有属性的对象的常量变量,那么它不会给我一个错误。

const example: One = {}; // no error why?

上述方法的另一个问题是const example = {} as One; 这也有效。

如果我不提供对象的索引签名,那么它会给我一个错误,提示您缺少属性。

interface Two {
 first: string;
 second: string;
}

const example2: Two: {}; // error missing properties
// to tackle this situation I used type assertion

const example3 = {} as Two; // no error

我的问题是为什么example 变量接受没有属性的对象?

您可能有一个问题,为什么我想要一个没有属性的对象。原因是我想稍后向那个空对象添加一些属性。这种情况下,我应该做类型断言还是类型注解?

【问题讨论】:

  • {} as Two 你是说“这绝对是一个二”,覆盖编译器:typescriptlang.org/docs/handbook/2/…。我不知道您为什么会期望One 出现错误,索引类型说可以设置任何以字符串命名的属性,但不需要任何要求
  • 我在这里感到困惑,任何以字符串命名的属性都包含空对象吗?
  • 显然它确实包含空对象,因为编译器没有出错。这样看:[key: string]: string 不能要求key每个 值都带有值,因为可以作为键的字符串范围几乎是无限的。因此它们都必须是可选的,因此空对象与具有一个或多个键的对象一样有效。
  • 这样说:前者允许编译器实际检查你是否正确;后者坚持认为你是。
  • @jonrsharpe “一个几乎无限的范围”......这让我感到疑惑。我认为从 ES2016 开始,字符串最多可以有少于 2^53 个 UTF-16 字符,所以最多 (2^16)^(2^53-1) 个可能的字符串,WolframAlpha tells me 小于 10^ (10^17)。所以,比 googol 大得多,但比 googolplex 小得多。当然不是无限的,但是如果它需要所有键都实际存在,则需要多个计算机内存来存储{[key: string]: string}。或使用Proxy。 ??????

标签: typescript index-signature


【解决方案1】:

在第一个示例中,您只是定义了索引的类型,并没有像使用 in 那样指定索引:

type Keys = 'first' | 'second'
type One = { [P in Keys]: string };

const one: One = {}; // Error: Type '{}' is missing the following properties from type 'One': first, second

在第二个示例中,您断言该值为 Two。您是在告诉 typescript 信任您。如果您想使用 Two 类型但将字段设为可选,则可以使用 Partial 实用程序类型。

const example2: Partial<Two> = {}; // valid
const example3: Partial<Two> = { first: '1' }; // valid
const example3: Partial<Two> = { third: '3' }; // Error: Object literal may only specify known properties.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2016-06-03
    • 2015-05-08
    • 1970-01-01
    • 2023-03-05
    • 2021-03-20
    • 1970-01-01
    相关资源
    最近更新 更多