angular - typescript 中的索引签名如何工作?

标签 angular typescript

尝试设置对象索引签名时出现错误的重复数字索引签名。这是工作示例 click here

    export class HelloComponent implements OnInit  {
      //works
      watched: { [id: number]: boolean } = {} ; //works
      //doesnt work
      watchedOne: { [id: number]: boolean, 
        [fid: number]: boolean } = {} ; // Doesn't Work
      constructor() {}

      watch(talk): void {
        console.log('watch', talk.id);
        this.watched[talk.id] = true;
        this.watchedOne[talk.id] = true; // error
        console.log('watch-obj', this.watched); 
    }
     ngOnInit() {
        this.watch({
          id: 9,
          fid: 4
        });
     }
    }

最佳答案

请通读 The TypeScript Handbook 中关于索引签名的部分和/或 TypeScript Deep Dive .

也许您想要索引签名的原因并不明确。如果你想定义一个类型并且你知道你关心的属性集,包括键名,那么你不需要索引签名。当有人访问没有索引签名的对象并使用未知键时,或者使用未知键分配新对象文字时,这是编译器错误:

const foo: {bar: boolean, baz: boolean} = {
  bar: true, 
  baz: false, 
  qux: false // error, extra property not expected
};
foo.bar;
foo.baz;
foo.qux; // error, no idea what qux is supposed to be
foo.quux; // error, no idea what quux is supposed to be

在上面的代码中,barbaz都被接受了,但是在qux上出现了错误。

相反,如果您想允许任何 键,而事先不知道它是什么,那么您可以添加一个索引签名:

const foo: {bar: boolean, baz: boolean, [k: string]: boolean | undefined} = {
  bar: true, 
  baz: false, 
  qux: false // no error
};
foo.bar;
foo.baz;
foo.qux; // boolean | undefined
foo.quux; // boolean | undefined

使用单个索引签名,您可以根据需要使用正确类型的键和值设置任意数量的属性。您在签名中为索引键提供的名称根本无关紧要;它是任何正确类型的键的占位符。 key 的两种可接受类型是 stringnumber

例如,使用单个number索引:

const foo: { [k: number]: boolean | undefined } = { };
foo[0] = true;
foo[1] = false;
foo[2] = void 0; // undefined
foo[12345] = true;
foo[54321] = false;
foo[1.5] = true;
foo[-4] = false;

请注意,索引签名中的 k 无关紧要。我通常使用 k,但你可以使用 keyrandom 或任何东西,因为这无关紧要。它只是一个占位符。


这意味着我可以通过执行以下操作使您的上述代码正常工作:

export class HelloComponent implements OnInit  {
  name: string = "karty";
  watched: { [id: number]: boolean } = {} ;
  // single index signature
  watchedOne: { [id: number]: boolean } = {} ;
  constructor() {}

  // type annotation on talk to ensure the right types
  watch(talk: {id: number, fid: number}): void {
    console.log('watch', talk.id);
    this.watched[talk.id] = true;
    this.watchedOne[talk.fid] = true;
    console.log('watch-obj', this.watched); 
}
 ngOnInit() {
    this.watch({
      id: 9,
      fid: 4
    });
 }
}

希望对您有所帮助;祝你好运!

关于angular - typescript 中的索引签名如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47037807/

相关文章:

angular - 过滤 Firebase 数据时,Where() 和 orderBy() 过滤器不能一起工作

angular - 'formDirective' 被定义为类 'ControlContainer' 中的访问器,但在 'ConnectArrayDirective' 中作为实例属性被覆盖

angular - 如何防止 Angular 7 站点上的浏览器缓存?

javascript - TypeScript/RxJS - 可观察的订阅()方法完成()未运行

javascript - 我如何在 React TypeScript 中引用文档?

javascript - Typescript/Angular 2 问题

html - 如何创建下拉列表并绑定(bind)来自服务器的数据

angular - 如何在 Angular 2 应用程序中使用 typescript 显示基于其他下拉值的下拉值

javascript - 通过泛型函数动态修改 TypeScript 类

node.js - Typescript+Node.js 中的 os.EOL