Within my project, I have introduced a generic entity type that utilizes a generic to determine a field type based on a specific set of string literals:
type EntityTypes = 'foo' | 'bar' | 'baz';
type EntityMappings = {
foo: string;
bar: number;
baz: Array<string>;
}
type GenericEntity<T extends EntityTypes> = {
type: T;
fieldProperty: EntityMappings[T];
}
The objective is to mandate all instances of GenericEntity to contain a single type
field (consisting of a string literal) that then defines the type of fieldProperty, as shown below:
const instance: GenericEntity<'foo'> = {
type: 'foo',
fieldProperty: 'hello',
};
const otherInstance: GenericEntity<'baz'> = {
type: 'baz',
fieldProperty: ['a', 'b', 'c'],
}
Nevertheless, due to the fact that T extends EntityTypes
permits a union of multiple string literal values from EntityTypes, it becomes possible to execute this undesired action:
const badInstance: GenericEntity<'foo' | 'baz'> = {
type: 'baz',
fieldProperty: 'blah',
};
This issue arises because now type
embodies 'foo' | 'baz'
and fieldProperty is composed of string | Array<string>
, thereby disrupting the intended alignment between the two fields.
I am seeking guidance on whether there exists a method to further restrict the generic declaration of GenericEntity to allow only a singular distinct string literal value. Alternatively, is there an alternative approach to ensure that every instance of GenericEntity contains both a type
field and a corresponding fieldProperty
field?