Javascript 为什么可以';这个索引签名不是可选的吗?
在TypeScript中,有一个预定义的类型称为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
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]}
都是允许的,并且表示相同的东西)