Reputation: 4958
I want to do something like
export interface Foobar {
foo: string;
bar?: any;
}
export interface Foobar<T> {
bar: T;
}
, so that bar
is an optional prop if no generic type is passed, but has to be of the generic type if one is set... i. e., I want to be able to do
const one: Foobar = { foo: 'foo' }; // bar is not required here
const two: Foobar<number> = { foo: 'foo', bar: 123 }; // `bar` is required here
The suggestion above throws
All declarations of 'Foobar' must have identical type parameters.
Is it possible to achieve this in some other way?
Upvotes: 1
Views: 1311
Reputation: 327624
I'm not sure what your use case is, but if you can use a type alias instead of an interface, then you could define Foobar
to be something like:
type Foobar<T = never> = {
foo: string;
} & ([T] extends [never] ? { bar?: any } : { bar: T });
This uses a generic parameter default to set T
to never
if you don't specify it, and a conditional type to choose either an optional bar
or a required bar
depending on the type of T
. It works the way you wanted:
const one: Foobar = { foo: "foo" }; // bar is not required here
const two: Foobar<number> = { foo: "foo", bar: 123 }; // `bar` is required here
Hope that helps; good luck!
Upvotes: 5