admin管理员组

文章数量:1336632

I have an Object with keys that I've typed and I want to loop over it and maintain their type, avoiding "Element implicitly has an 'any' type because 'ContactList' has no index signature".

I know this has been discussed at length on Typescript's GitHub pages but I haven't found any solutions for what I'm trying to do here. Trying it both with enums and with unions, but I still get the error.

Example with enums (playground)

enum Names {
  Joe,
  Bill,
  Bob
}

type ContactList = {
  [key in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  [Names.Joe]: {
    isFriend: true,
  },
  [Names.Bill]: {
    isFriend: false,
  },
  [Names.Bob]: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

Example with unions (playground)

type Names = 'joe' | 'bill' | 'bob'

type ContactList = {
  [K in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  joe: {
    isFriend: true,
  },
  bill: {
    isFriend: false,
  },
  bob: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

Either way, I'm telling typescript "the only keys allowed in this object are from Names" and as far as I understand index signatures, [key in Names] should be one, so I'm not sure why I'm seeing an error. Sorry if this is a noob question, I'm a little green with TS still. Thanks.

I have an Object with keys that I've typed and I want to loop over it and maintain their type, avoiding "Element implicitly has an 'any' type because 'ContactList' has no index signature".

I know this has been discussed at length on Typescript's GitHub pages but I haven't found any solutions for what I'm trying to do here. Trying it both with enums and with unions, but I still get the error.

Example with enums (playground)

enum Names {
  Joe,
  Bill,
  Bob
}

type ContactList = {
  [key in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  [Names.Joe]: {
    isFriend: true,
  },
  [Names.Bill]: {
    isFriend: false,
  },
  [Names.Bob]: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

Example with unions (playground)

type Names = 'joe' | 'bill' | 'bob'

type ContactList = {
  [K in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  joe: {
    isFriend: true,
  },
  bill: {
    isFriend: false,
  },
  bob: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

Either way, I'm telling typescript "the only keys allowed in this object are from Names" and as far as I understand index signatures, [key in Names] should be one, so I'm not sure why I'm seeing an error. Sorry if this is a noob question, I'm a little green with TS still. Thanks.

Share Improve this question asked Mar 5, 2019 at 21:22 hello_lukehello_luke 94713 silver badges15 bronze badges 1
  • It sounds weird... with the union you can write a workaround: (Object.keys(contactList) as Names[]). It doesn't work with the enum. – Joel Commented Mar 5, 2019 at 21:36
Add a ment  | 

1 Answer 1

Reset to default 7

As Object.keys might return more properties than the object actually contains by type, the return type of it is intentionally typed as string[]. Otherwise, it would be pretty mon for well-typed code to throw unexpected exceptions at runtime, as explained in this answer.

Therefore you have to make your index type work on strings:

type ContactList = {
  [key: string]: {
    isFriend: boolean;
  },
};

Or you typecast and hope for the best:

contactList[name as Names]

Also you could just:

console.log(...Object.values(contactList));

本文标签: javascriptAvoid implicit 39any39 type when using Objectkeys in TypescriptStack Overflow