mindparse
mindparse

Reputation: 7295

Enforce the name of an interface field must equal value of another field

I have an interface as follows:

export interface DashboardRequest {
  name: string;
  type: string;
  [key:string]: any;
}

I was wondering if its possible to enforce that the field name of my third dynamic keyed field must be equal to whatever the value is for the type field?

e.g

const request:DashboardRequest = {
  name: 'foo';
  type: 'bar;
  bar: 5;
}

Is this possible?

Upvotes: 0

Views: 31

Answers (1)

cdimitroulas
cdimitroulas

Reputation: 2549

I feel like there must be a better way, but I was able to get something along the lines of what you need in this manner:

type DashboardRequest<T extends string> = {
  name: string;
  type: T;
} & { [K in T]: any }

// annoying that you need to pass the type argument here :(
const request: DashboardRequest<'bar'> = {
  name: 'foo',
  type: 'bar',
}
// Compiler error:
//   Property 'bar' is missing in type '{ name: string; type: "bar"; }'
//   but required in type '{ bar: any; }'.


// Edit:
//   Thanks to Titian Cernicova-Dragomir for the idea to use a helper 
//   function to avoid needing to specify the type manually 
const DashboardRequest = {
  create: <T extends string>(o: DashboardRequest<T>) => o
}

// this also gives the correct compiler error
const req = DashboardRequest.create({ name: 'foo', type: 'bar' })

Upvotes: 4

Related Questions