UsainBloot
UsainBloot

Reputation: 816

Mandatory key in interface based on optional generic

Is there a way in Typescript to make an interface have a mandatory key when a generic is passed into it?

I am looking for a way to be able to defined types for keys in interfaces only when a Generic is passed into it.

eg.

interface IExample {
  foo: string
}
​
/* You can't declare 2 interfaces of the same name, but this shows the structure I am aiming for */
interface IExample<T> {
  foo: string,
  bar: T
}
​
/* Allowed */
const withoutBar: IExample {
  foo: 'some string'
}
​
/* Not allowed, as I've passed in a generic for Bar */
const withoutBar: IExample<number> {
  foo: 'some string'
}
​
/* Allowed */
const withBar: IExample<number> {
  foo: 'some string',
  bar: 1
};
​
/* Not allowed as I have not passed in a generic for Bar */
const withBar: IExample {
  foo: 'some string',
  bar: 1 // Should error on "bar" as I have not passed in a generic
};

Upvotes: 2

Views: 523

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

You could a type alias with a conditional type.

type IExample<T = void> = T extends void ?  {
  foo: string
} : {
  foo: string,
  bar: T
}
​​
/* Allowed */
const withoutBar: IExample = {
  foo: 'some string'
}
​
/* Not allowed, as I've passed in a generic for Bar */
const withoutBar: IExample<number> = {
  foo: 'some string'
}
​
/* Allowed */
const withBar: IExample<number> = {
  foo: 'some string',
  bar: 1
};
​
/* Not allowed as I have not passed in a generic for Bar */
const withBar: IExample = {
  foo: 'some string',
  bar: 1 // Should error on "bar" as I have not passed in a generic
};

Playground

Upvotes: 2

Related Questions