diff --git a/docs/object.md b/docs/object.md index eebeef2..27c7768 100644 --- a/docs/object.md +++ b/docs/object.md @@ -683,7 +683,19 @@ computeDistance({x: 1, y: 2}); // 正确 ## 最小可选属性规则 -如果一个对象的所有属性都是可选的,会触发最小可选属性规则。 +根据“结构类型”原则,如果一个对象的所有属性都是可选的,那么其他对象跟它都是结构类似的。 + +```typescript +type Options = { + a?:number; + b?:number; + c?:number; +}; +``` + +上面示例中,类型`Options`的所有属性都是可选的,所以它可以是一个空对象,也就意味着任意对象都满足`Options`的结构。 + +为了避免这种情况,TypeScript 2.4 引入了一个“最小可选属性规则”,也称为[“弱类型检测”](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html#weak-type-detection)(weak type detection)。 ```typescript type Options = { @@ -692,24 +704,16 @@ type Options = { c?:number; }; -const obj:Options = { - d: 123 // 报错 -}; +const opts = { d: 123 }; + +const obj:Options = opts; // 报错 ``` -上面示例中,类型`Options`是一个对象,它的所有属性都是可选的,这导致任何对象实际都符合`Options`类型。 +上面示例中,对象`opts`与类型`Options`没有共同属性,赋值给该类型的变量就会报错。 -为了避免这种情况,TypeScript 添加了最小可选属性规则,规定这时属于`Options`类型的对象,必须至少存在一个可选属性,不能所有可选属性都不存在。这就是为什么上例的`myObj`对象会报错的原因。 +报错原因是,如果某个类型的所有属性都是可选的,那么该类型的对象必须至少存在一个可选属性,不能所有可选属性都不存在。这就叫做“最小可选属性规则”。 -这条规则无法通过中间变量规避。 - -```typescript -const myOptions = { d: 123 }; - -const obj:Options = myOptions; // 报错 -``` - -上面示例中,即使使用了中间变量`myOptions`,由于存在最小可选属性规则,依然会报错。 +如果想规避这条规则,要么在类型里面增加一条索性属性(`[propName: string]: someType`),要么使用类型断言(`opts as Options`)。 ## 空对象