typescript - 为什么打字稿未定义类型的行为与可选类型不同?
问题描述
想象一下我们有接口
interface Foo {
bar: number | undefined;
}
如果我们尝试创建 Foo 类型的对象,例如
const foo: Foo = {};
它不会编译,因为缺少属性栏。但是我们说它可以是未定义的,如果我们将它显式设置为未定义,这将起作用,但如果我们根本不设置它,那是完全一样的。它不应该与以下完全相同吗?
interface Foo {
bar?: number;
}
对我来说这是一个问题,因为如果我们考虑更复杂的例子,我们有一个字段接口,它可以是泛型类型的可选。就像,如果没有指定泛型类型,那么字段应该是未定义的,如果指定了,那么它应该只是那个类型。例如
interface Foo<T = undefined> {
bar: T;
title: string;
}
const foo1: Foo = {
title: 'TITLE'
};
const foo2: Foo<number> = {
title: 'title',
bar: 12
};
foo1 将无法编译,因为缺少属性,但无论如何它都必须是未定义的,如果我们明确指定它,它将起作用,但这完全一样。我最终通过继承解决了这个问题,其中基类没有任何通用参数,并且子类对其进行了严格指定。但我只是好奇是否有人知道以这种方式处理未定义类型的具体原因。因为我自己找不到任何关于它的信息。
解决方案
这两种类型的签名并不完全等价(尽管它们足够接近以至于乍一看差异可能并不明显)!
bar?: number
表示对象可能没有名为 的字段bar
。bar: number | undefined
表示对象将始终有一个名为 的字段bar
,但该字段的值可能设置为undefined
。
在某些情况下,这种差异可能很重要,因为某些运行时行为取决于存在的字段与设置为未定义的字段之间的差异 - 考虑是否调用Object.keys
了对象:
Object.keys({ bar: undefined }) // returns ["bar"]
Object.keys({}) // returns []
推荐阅读
- c# - 为什么允许我们从线程池线程修改表单标题?
- c# - 如何防止 Razor 视图中自定义 Html 助手的摆动?
- ibm-cloud - 如何将 MQTT Dashboard、IOT MQTT Panel 等可用应用程序连接到 IBM BlueMix
- firebase - 如何在 Firebase 测试实验室中执行指定测试
- python - Python 函数仅在 Django 上的服务器启动后工作一次
- ios - 如何附加到 testflight 应用程序中发布的调试?
- python - ValueError: X.shape[1] = 8 应该等于 1500,训练时的特征数
- javascript - 如何读取辣椒机器人的二维码?
- asp.net - 单击按钮时未填写runat服务器字段?
- java - JavaFX:使用控制器更改场景