Jason
Jason

Reputation: 1858

Typescript : Property does not exist on type 'object'

I have the follow setup and when I loop through using for...of and get an error of :

Property "country" doesn't exist on type "object".

Is this a correct way to loop through each object in array and compare the object property value?

let countryProviders: object[];

export function GetAllProviders() {
   allProviders = [
      { region: "r 1", country: "US", locale: "en-us", company: "co 1" },
      { region: "r 2", country: "China", locale: "zh-cn", company: "co 2" },
      { region: "r 4", country: "Korea", locale: "ko-kr", company: "co 4" },
      { region: "r 5", country: "Japan", locale: "ja-jp", company: "co 5" }
   ]

   for (let providers of allProviders) {
      if (providers.country === "US") { // error here
         countryProviders.push(providers);
      }
   }
}

Upvotes: 159

Views: 528545

Answers (5)

Shonubi Korede
Shonubi Korede

Reputation: 591

If you want to strongly type, you could do

type ProviderKeys = 'region' | 'country' | 'locale' | 'company'

type Provider = Record<ProviderKeys, string>;

const countryProviders: Provider[] = [];
let allProviders: Provider[] = []

Upvotes: 0

Marcel
Marcel

Reputation: 770

Yes you should try to avoid object, any etc. if you can, after all the thing is called TypeScript for a reason.

If, however, you need a working dirty trick:

let o: object = { id: 1 }
console.log(o.id);                // throws error
console.log((o as any).id);       // fine

As always: anything goes with any.

Upvotes: 9

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

If your object contains any key/value pairs, you could declare an interface called keyable like :

interface keyable {
    [key: string]: any  
}

then use it as follows :

let countryProviders: keyable[];

or

let countryProviders: Array<keyable>;

For your specific case try to define the key type and use Record utility to define the object :

type ProviderKey="region" | "country" | "locale" | "company"

let countryProviders: Array<Record<ProviderKey,string>>;

Upvotes: 60

Hari Prasanna Addanki
Hari Prasanna Addanki

Reputation: 439

Yes the above methods are highly recommended, but if you have no choice and want to continue using "allProviders" as an array of object, then go for this method. This worked for me without creating an interface.

if(providers["country"] === "US") // replacement

Upvotes: 15

Saravana
Saravana

Reputation: 40534

You probably have allProviders typed as object[] as well. And property country does not exist on object. If you don't care about typing, you can declare both allProviders and countryProviders as Array<any>:

let countryProviders: Array<any>;
let allProviders: Array<any>;

If you do want static type checking. You can create an interface for the structure and use it:

interface Provider {
    region: string,
    country: string,
    locale: string,
    company: string
}

let countryProviders: Array<Provider>;
let allProviders: Array<Provider>;

Upvotes: 165

Related Questions