Typescript对象索引器和与索引器类型不匹配的键

时间:2019-02-10 19:08:36

标签: javascript typescript

Typescript文档显示以下示例:

interface NumberDictionary {
    [index: string]: number;
    length: number;    // ok, length is a number
    name: string;      // error, the type of 'name' is not a subtype of the indexer
}

以上示例的建议解决方法是什么,例如我有一个我知道有name: string属性的对象,它可以有其他可能的键,所有键都必须是数字吗?

2 个答案:

答案 0 :(得分:2)

问题是这种类型固有地不一致。考虑以下代码:

let prop = Math.random() > 0.5 ? "name" : "other"
let dic: NumberDictionary;
let value = dic[prop] // typed as number but could end up as string at runtime

索引定义告诉我们number,但在运行时可能会以string结尾。

诚实的做法是使索引签名返回number | string

interface NumberDictionary {
    [index: string]: number | string;
    length: number;
    name: string;
}
let prop = Math.random() > 0.5 ? "name" : "other"
let dic: NumberDictionary;
let value = dic[prop] // typed as number | string we need a type guard to tell teh difference

诚实的解决方案可能并不总是可行的,并且在完全意识到危险之后,您可以定义一个相交类型,以使您摆脱不一致的情况:

type NumberDictionary = {
  [index: string]: number;
} & {
  length: number;    
  name: string;
}

let prop = Math.random() > 0.5 ? "neverName" : "other"
let dic: NumberDictionary = {
  name: "",
  length: 1
} as NumberDictionary; // type assertion necessary, ts will still complain here about the inconsistentcy 
let value = dic[prop] // typed as number, hope everyone avoids passing in name

答案 1 :(得分:1)

赞:

interface NumberDictionary {
    [index: string]: number | string;
    length: number;
    name: string;
}