#Can anyone explain me the index signature with object type?

35 messages · Page 1 of 1 (latest)

weak coral
#

I am reading through official doc and there is one example code to describe string vs number index type. But I don't quiet get why this is marked as error in TS.

The following line [x: number]: Animal; in the below code.

interface Animal {
  name: string;
}
 
interface Dog extends Animal {
  breed: string;
}
 
// Error: indexing with a numeric string might get you a completely separate type of Animal!
interface NotOkay {
  [x: number]: Animal;
'number' index type 'Animal' is not assignable to 'string' index type 'Dog'.
  [x: string]: Dog;
}
ionic bluff
#

@weak coral are you sure the code snipped you posted is right?

#

so basically, when you are using index signatures, they have to be compatible

weak coral
ionic bluff
#

basically, since JS turns numbers keys into string
the objects associated to numbers must be compatible with the ones associated with strings

#
interface Ok {
    [x: string]: Animal;
    [x: number]: Dog; // allowed, since Dogs are (subtypes of) Animal
}

interface NotOkay {
    [x: string]: Dog;
    [x: number]: Animal; // not allowed, since not all Animals are Dogs
}
#

[x: number]: Dog; will turn into [x: string]: Dog;
and [x: string]: Dog; is a subtype of [x: string]: Animal;

#

[x: number]: Animal; will turn into [x: string]: Animal;
but [x: string]: Animal; is not a subtype of [x: string]: Dog;

#

@weak coral

weak coral
#

This example and explanation is very much clear .. thank you Pro

ionic bluff
#

I agree that the example in the handbook isn't very clear

weak coral
#

You submit a edit request to the doc with your example. That will help many

#

Could you explain this example?

interface NumberDictionary {
  [index: string]: number;
 
  length: number; // ok
  name: string;
Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
}
#

Why length: number is ok but not the name: string not?

#

@ionic bluff

ionic bluff
#

it's bacause of [index: string]: number;, which says all associated values will be numbers

#

but this conflicts with name: string;, whose associated value is a string

weak coral
#

do we check compatbility against the first property in the object?

ionic bluff
#

no, not really

#

but the [index: string]: number; kinda acts like a "match all" or "default"

weak coral
#

ok

ionic bluff
#

so any other attribute specified must be compatible with that

weak coral
#

ok

ionic bluff
#

[index: string]: number; and length: number; can be merged together

#

but name: string; cannot be merged with [index: string]: number;

#

if you want to specify additional properties that are not compatible with the indexed properties, you will have to write an intersection

turbid daggerBOT
#
interface NumberDictionary {
    [index: string]: number;
    length: number;
}

type NamedNumberDictionary = NumberDictionary & {
    name: string;
}

declare const dic: NamedNumberDictionary;

const foo = dic["foo"];
//    ^? - const foo: number

const name_ = dic.name;
//    ^? - const name_: string
ionic bluff
#

like so

weak coral
#

Which are some other good resources to learn TS throughly ?

ionic bluff
#

I've only ever read the TS handbook

#

and personal experience

#

but to be fair, you don't need to learn everything at once, start with the basics
try those out in personnal projects
then learn what you need along the way

#

also, I'd suggest having a look at the What's New section of the handbook, since there is a lot of stuff that got added to the language that isn't in the main handbook anywhere, only in the release notes