为什么索引类型定义了两次?

时间:2016-09-20 16:57:05

标签: typescript

这是打字稿official document的示例:

class Animal {
    name: string;
}
class Dog extends Animal {
    breed: string;
}

// Error: indexing with a 'string' will sometimes get you a Dog!
interface NotOkay {
    [x: number]: Animal;
    [x: string]: Dog;
}

令我困惑的是索引类型定义:

interface NotOkay {
    [x: number]: Animal;
    [x: string]: Dog;
}

在我的印象中,索引类型就像一个数组(javascript中的一个对象)。您只能使用" []"访问该成员。运营商,例如:

a [10],或[" Tom"]。

为什么上面的例子定义了两次索引并返回? 第一次:

[x: number]: Animal;

第二次:

[x: string]: Dog;

使用[]运算符时,哪一个应该是类型?例如一个[10] ...

1 个答案:

答案 0 :(得分:1)

  

使用[]运算符时,哪一个应该是类型?例如一个[10] ...

在JavaScript中(因此在TypeScript中)对象可以具有以数字作为名称的属性,例如:

{
    1: 'Apples',
    2: 'Oranges'
}

与以下内容相同:

{
    '1': 'Apples',
    '2': 'Oranges'
}

属性的名称也称为

  

在我的印象中,索引类型就像一个数组(javascript中的一个对象)。

仅仅因为一个对象有数字键,它自动成为一个数组:

var arr = ['Apples', 'Oranges'];
console.log(arr.constructor); // logs 'function Array() { ... }'
console.log(arr[1]); // logs 'Apples'

var obj = { 1: 'Apples', 2: 'Oranges' };
console.log(obj.constructor); // logs 'function Object() { ... }'
console.log(obj[1]); // logs 'Apples'
console.log(obj['1']); // logs 'Apples'

话虽如此,接口NotOkay描述了允许 数字和非数字键的对象。它们的访问方式不受任何方式的接口描述或限制。

  

令我困惑的是索引类型定义

烨。这正是你所提到的TypeScript手册的含义'使用'string'索引有时会让你成为狗'。由于我刚刚描述的访问器语法松散,因此有一个对象,其数字键可以访问一种类型,而非数字键可以访问另一种类型,这将非常令人困惑。

为了清楚起见:如果你稍微修改一下这个例子,接口就不会有错误了:

class Animal {
    name: string;
}
class Dog extends Animal {
    //breed: string; <-- Dog and Animal now have the same interface 
}

// No error because Dog and Animal have the same interface:
interface Okay {
    [a: number]: Animal;
    [x: string]: Dog;
}

TypeScript playground

这个例子很好,因为TypeScript使用结构类型系统

  

TypeScript中的类型兼容性基于结构子类型。   结构化打字是一种仅根据其类型来关联类型的方式   成员。这与名义打字形成对比。 more...

希望这会帮助你。