TypeScript允许设置属性但不能访问(索引签名)

时间:2016-09-29 08:29:22

标签: typescript

此界面是TypeScript文档中的一个示例 编译器显示height的错误,即使它允许我设置它?

// Interface taken from https://www.typescriptlang.org/docs/handbook/interfaces.html
interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}

const sq = <SquareConfig>{
    color: 'red',
    width: 7890,
    height: 888
}

console.log(sq.height); // Property 'height' does not exist on type 'SquareConfig'

2 个答案:

答案 0 :(得分:4)

现在问题中的代码有效。

从TypeScript 2.2开始,可以使用以下语法访问字典成员:x.propName。这是the announcement

  

在TypeScript 2.2之前,编写x["propName"]之类的东西是您使用字符串索引签名来获取属性的唯一方法。有点令人惊讶的是,不允许编写像x.propName这样的属性访问权限。这与JavaScript的实际工作方式略有不同,因为x.propName在语义上与x["propName"]相同。当存在索引签名时,允许两种形式都有合理的论据。

     

在TypeScript 2.2中,我们正在做这件事并放宽旧的限制。这意味着像测试JSON对象上的属性这样的东西变得更加符合人体工程学。

原始答案(在TypeScript 2.2之前)

syntax of indexable types用于定义用作地图的对象属性的类型。例如:

interface Colors {
  [propName: string]: string
}
let colors: Colors = /* here, we provide the map */;
colors['blue'].indexOf('#'); // OK, "indexOf" can be used because the type is string

这是一种定义使用语法obj['propertyName']动态命名的属性类型的方法。它不是定义任何静态属性的方法,即使JavaScript允许它:

colors.blue // TS Error: Property 'blue' does not exist on type 'Colors'

因此,使用any而不是真实类型的以下可索引类型是无用的:

[propName: string]: any;

规范(在TS 2.2之前)

来自the specification

  

3.9.4索引签名

     

索引签名为包含类型中的属性定义类型约束。

     

IndexSignature:   [ BindingIdentifier : string ] TypeAnnotation    [ BindingIdentifier : number ] TypeAnnotation

     

[...]

     

索引签名会影响确定将括号表示法属性访问应用于包含类型的实例所导致的类型,如4.13部分所述。

答案 1 :(得分:1)

我个人可以访问它:我看到输出&#39; 888&#39;在我的控制台中。

我使用以下语法删除编译警告:

sq['height']

希望它可以提供帮助。