打字稿 - 了解界面的索引器

时间:2018-05-02 10:11:17

标签: typescript

索引器有点令人困惑。

示例:

interface Notes {
    [noteId: number]: string[];
}
  1. 即使我将noteId键入number,我仍然可以传递一个字符串:
  2. var notes: Notes;
    notes['1'] = ['Some note'];

    所以我假设强制发生了。但什么时候?

    1. 如果圆括号的作用相同,为什么要使用方括号:
    2.     interface Notes {
              (noteId: number): string[];
          }

      是的,我也可以将它作为一个功能使用,但我认为这更像是一个不利的优势..

      P.S。对不起该帖子中的混乱,似乎StackOverflow无法设法解决这个古老而烦人的错误......

2 个答案:

答案 0 :(得分:2)

嗯,

之间的区别
interface Notes {
    [key: number]: string;
}

interface Notes2 {
    [key: string]: string;
}

就是那个

const t: Notes = {};
const t2: Notes2 = {};
t.d = ['value']; // error!
t2.d = ['value']; // OK

圆括号不起作用,它们定义函数,而不是对象:

interface Notes3 {
    (key: string): string[];
}

const t3: Notes3 = {}; // Error! {} not assignable to Notes3
t3.d = ['value']; // Error again! Notes3 has no 'd' property.

const t4: Notes3 = (key: string) => [key]; // OK!
const b = t4('hello'); // b is of type string[] and its value = ['hello']

我认为t[...]t2[...]等工作的原因(我不认为),由于性能原因,TypeScript没有对括号中的索引进行类型检查,或者可能与JavaScript的广泛兼容性。

我认为,在过去的版本中,它确实正确地检查了这些索引。

答案 1 :(得分:1)

关于第一个示例 - 您需要打开noImplicitAny编译器选项,然后您将收到预期的错误。

至于第二个 - 它是相同,它是“可调用签名”,例如:

interface GetNotes {
    (noteId: number): string[];
}

const getNotes: GetNotes = (noteId: number) => [];