Javascript 为什么可以';这个索引签名不是可选的吗?

Javascript 为什么可以';这个索引签名不是可选的吗?,javascript,typescript,Javascript,Typescript,在TypeScript中,有一个预定义的类型称为Partial。它是这样定义的: type Partial<T> = { [P in keyof T]?: T[P]; } interface IDictionary<T> { [ key: string ]?: T } 类型部分={ [P在keyof T]?:T[P]; } 显然,索引签名被标记为可选的,这是有效的。如果我尝试这样做: type Partial<T> = { [P in key

在TypeScript中,有一个预定义的类型称为
Partial
。它是这样定义的:

type Partial<T> = {
  [P in keyof T]?: T[P];
}
interface IDictionary<T> {
  [ key: string ]?: T
}
类型部分={
[P在keyof T]?:T[P];
}
显然,索引签名被标记为可选的,这是有效的。如果我尝试这样做:

type Partial<T> = {
  [P in keyof T]?: T[P];
}
interface IDictionary<T> {
  [ key: string ]?: T
}
接口IDictionary{ [键:字符串]?:T }
TypeScript抱怨
。这是因为接口可能不包含可选字段,还是原因是什么?

否,typescript接口允许使用可选字段。原因是从逻辑上讲,这毫无意义

Partial
在keyof T中添加了一个键的外观约束=>
p。
如果您要删除
,这意味着
部分
T
相同

接口车{
品牌:弦;
颜色:字符串;
}
//这与下面的接口声明完全相同
类型PartialCar=部分;
//这与上面的类型完全相同
接口PartialCar={
品牌?:字符串;
颜色?:字符串;
}
不带颜色的const CAR:PartialCar={品牌:“宝马”}
常量thisistillapartialcar:PartialCar={}
对于您的
i词典
,它是不同的。您没有在键上添加约束(只是说它是任何
字符串
)。所以说它可以是可选的是没有意义的,因为它无论如何都是可选的(就它可以是任何
字符串而言)。
在您的
IDictionary
中,您只是在值部分添加了一个约束,该值部分的类型必须是
T

const numberDictionary:IDictionary={someStupidKey:1,oneMoreKey:2}
const stringDictionary:IDictionary={someStupidKeyAWFSAFWAFW:“foo”,oneMoreKey:“bar”}
//typescript将假定“someVariable”是一个数字
const someVariable=numberDictionary.this未定义;
//这就是为什么这不会导致编译错误,而是运行时错误
const someResult=1+someVariable;

正如您所看到的,每个键都是可选的,您可以通过声明
IDictionary

Partial
定义是一个映射类型,它说:“检查所有成员并添加可选修饰符”。通过将索引签名标记为可选,您试图实现什么?看起来很像,但不一样。索引签名不能被标记为可选的,实际上总是被视为可选的(在某种意义上,您不需要在匹配的对象中拥有所有可能的索引键);没有办法说“必须”。我同意语法令人困惑,可能会产生误导,但事实就是如此。这听起来是正确的,但仍然存在一个问题,即为什么
[P in keyof T]
表示T的所有键,而
[P in string]
仅表示某些(任何)字符串。没有有限数量的键会满足“所有字符串”约束这一事实并不能证明imo的模糊表示法是正确的。我认为说索引签名键是可选的是多余的(而且不受支持),而不是说它“毫无意义”。这当然是有道理的,并且在TS中允许一些冗余结构(例如,
{a?:string}
{a?:string | undefined}
都是允许的,并且表示相同的东西;
{[K in keyof T]?:T[K]}
{[K in keyof T]+?:T[K]}
都是允许的,并且表示相同的东西)