在此代码段中,我通过接口将新属性添加到对象类型约束中:
let a: { p1: string, p2: number };
interface i1 { p1: string, p2: number };
let b: i1;
b = { p1: "hello", p2: 3 }; //no error no problem
/*
the following line gives this error:
Type '{ p1: string; p2: number; p3: number; }' is not assignable to type '{ p1: string; p2: number; }'.
Object literal may only specify known properties, and 'p3' does not exist in type '{ p1: string; p2: number; }'.
*/
a = {p1:"hello",p2:6, p3:3}
//this line give no compile error
a["123"] = 123;
我认为我使用对象文字给 a 的类型等同于我使用具有相同对象文字的接口给 b 的类型。
为什么我可以向不具有该属性的对象类型添加新属性,但是在分配具有附加属性的对象时出现错误?是不是不允许我向类型不具有破坏类型保证的属性的变量添加其他属性?
答案 0 :(得分:3)
接口和对象类型之间的行为是一致的:
olivere/elastic
上面的代码在let a: { p1: string, p2: number };
interface i1 { p1: string, p2: number };
let b: i1;
// both these give an error that p3 are excess properties
b = { p1: "hello", p2: 3, p3: "" };
a = {p1:"hello",p2:6, p3:3}
和a
上均给出了错误,指出不应b
。此功能称为多余属性检查,仅在将对象文字直接分配给给定类型的变量时起作用。 (请参见docs)
如果未启用编译器选项p3
,则a["123"] = 123
或b["123"] = 1123
上不会出现错误,这是默认行为,允许您建立索引默认情况下为空。
我的建议是打开noImplictAny
以便将这些对象索引,这是常见的错误来源。
如果要允许索引到对象中,则需要通过添加索引签名来明确显示该对象。如果可以,您可以在noImplictAny
下建立索引,并且多余的属性检查错误消失了:
noImplictAny