Reputation: 2186
I have a type defined that is an OR of strings(this cannot be an enum due to unrelated circumstances)
export type AnimalTypes =
| 'dog'
| 'cat'
| 'donkey'
| 'elephant';
I use this type as the value in an exported Record
export const PartyTypes: Record<string, AnimalTypes> = {
DOG_PARTY: 'dog',
CAT_PARTY: 'cat',
DEMOCRAT_PARTY: 'donkey',
REPUBLICAN_PARTY: 'elephant',
};
In a separate file I import the two above and make an interface with the AnimalType
as the key
interface ElectionState {
votesByParty: Record<AnimalTypes, PartyVotesCollection>;
}
When I try to make an object literal implementing this interface using the PartyTypes
Record I get an error on the object key
export const initialState: ElectionState = {
votesByParty: {
PartyTypes.DOG_PARTY: {
electionsWon: 0,
voteCount: 0,
},
},
};
Type '{ PartyTypes: Record<string, AnimalTypes>; "": any; }' is not assignable to type 'Record<AnimalTypes, PartyVotesCollection>'. Object literal may only specify known properties, and 'PartyTypes' does not exist in type 'Record<AnimalTypes, PartyVotesCollection>'.ts(2322)
What can I do to use the value of a Record as the key in another object that inherits from an interface?
Upvotes: 0
Views: 766
Reputation: 36924
Something to note:
export const initialState: ElectionState = {
votesByParty: {
PartyTypes.DOG_PARTY: 0,
},
};
should be
export const initialState: ElectionState = {
votesByParty: {
[PartyTypes.DOG_PARTY]: 0,
},
};
Also, the votesByParty
type require all the parties ( unless you want to make a partial type out of it )
export const initialState: ElectionState = {
votesByParty: {
[PartyTypes.DOG_PARTY]: 0,
[PartyTypes.CAT_PARTY]: 0,
[PartyTypes.DEMOCRAT_PARTY]: 0,
[PartyTypes.REPUBLICAN_PARTY]: 0,
},
};
This is still erroring out, because PartyTypes.DOG_PARTY
can be any kind of AnimalTypes
, so we cannot guarantee that votesByParty
will have all of them. After all, this:
export const PartyTypes: Record<string, AnimalTypes> = {
DOG_PARTY: 'cat',
CAT_PARTY: 'cat',
DEMOCRAT_PARTY: 'cat',
REPUBLICAN_PARTY: 'cat',
};
is still valid.
Because we need to be sure that votesByParty
have all the parties in it, we need to change:
export const PartyTypes = {
DOG_PARTY: 'dog',
CAT_PARTY: 'cat',
DEMOCRAT_PARTY: 'donkey',
REPUBLICAN_PARTY: 'elephant',
} as const;
unless you want to remove the requirement of having all the parties in the object, in that case:
interface ElectionState {
votesByParty: Partial<Record<AnimalTypes, number>>;
}
Upvotes: 1