2

I have the following enum and data models defined:

const enum Models {
  Location = 'Location',
  Person = 'Person',
  Vehicle = 'Vehicle'
}

export interface Location {
  name?: string,
  city?: string,
  state: string,
  zip?: string,
}

export interface Person {
  firstname: string,
  lastname?: string,
}

export interface Vehicle {
  model: string,
  year?: string,
}

I define my data as below:

type ModelMap = {[key in Models]: Location | Person | Vehicle}

const data: ModelMap = {  
  [Models.Location]: { state: 'CA' },
  [Models.Location]: { state: 'OR' },
  [Models.Location]: { state: 'CO', firstname: 'blah' },
  [Models.Person]: { firstname: 'John', lastname: 'Doe' },
  [Models.Vehicle]: { model: 'Ford', year: '2018' },
}

This works, but does not enforce specific types per object. Instead it enforces the union of the three types, Location | Person | Vehicle.

Is it possible to enforce the specific object type to match the enum index key? If so, how can it be done?

For example, I would like the 3rd location object to fail type checking, because the Location interface does not have a firstname variable. It seems like I am missing the mapping between the enum Models and the individual interfaces but I am not sure. Any help is appreciated. Thanks.

2
  • 1
    You can define a an interface mapping between the enum and the interface type and use it in the mapped type, but at that point I'm not sure there would be any benefit from the mapped type.. Commented Jan 6, 2019 at 18:49
  • Well that was easier than I thought. Thanks. A simple mapping between the interface and the key gives me the desired behavior. Commented Jan 6, 2019 at 19:26

1 Answer 1

3

I ended up creating a mapping between the interfaces and the enum as follows:

type EnumInterfaceMap = { Location: Location; Person: Person; Vehicle: Vehicle };
type ModelMap = {[key in Models]: EnumInterfaceMap[key]}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.