Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does index signature in typescript works?

I have an error duplicate number index signature when trying to set object index signature. Here is the working example 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
        });
     }
    }
like image 266
Karty Avatar asked Oct 23 '25 04:10

Karty


1 Answers

Please read through the sections on index signatures in The TypeScript Handbook and/or TypeScript Deep Dive.

Maybe it's not explicit in there why you want an index signature. If you want to define a type and you know the set of properties you care about, including the key names, then you don't want an index signature. When someone accesses an object without an index signature and uses an unknown key, or assigns a fresh object literal with an unknown key, it's a compiler error:

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

In the above code, bar and baz are accepted, but there's an error on qux.

If, instead, you want to allow any key, without knowing in advance what it will be, then you can add an index signature:

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

With a single index signature you can set as many properties with the right type of key and value as you want. The name you give the index key in the signature doesn't matter at all; it is a placeholder for any key of the right type. The two acceptable types for the key are string and number.

For example, using a single number index:

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;

Note that the k in the index signature doesn't matter. I usually use k, but you can use key or random or anything, because it doesn't matter. It's just a placeholder.


That means I can make your above code work by doing something like this:

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
    });
 }
}

Hope that helps; good luck!

like image 183
jcalz Avatar answered Oct 25 '25 17:10

jcalz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!