Reputation: 816
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
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
};
Upvotes: 2