Reputation: 444
Imagine you have a Foo interface that receives a generic type T like
interface Foo<T> {
...
bar: T;
}
now you want the T type to be optional, so you set an default value
interface Foo<T = undefined> {
...
bar: T;
}
but 'bar' is still required.
How do I get 'bar' to be required (not undefined) when type T is set, and remove it (or set it as not required) when Type T is not set?
I've tried something like the lines bellow, but 'bar' is still required. I could add a question mark to the 'bar' property but then 'bar' will not be required when T is set.
interface Foo<T = undefined> {
...
bar: T extends undefined ? never : T;
}
Any idea if this is even possible?
Upvotes: 1
Views: 436
Reputation: 7239
This should work
type Foo<T = undefined> = T extends undefined ? {} : {
bar: T
}
const foo : Foo = { bar: "hello" }
const bar: Foo<string> = { bar: "hello" }
const foobar : Foo = {}
Upvotes: 3
Reputation: 249466
Depends why you need this, the base and derived interface solution is pretty good for most situations (presented in another answer here).
You can't use a conditional type to make a field optional. But you can use an intersection type instead:
type Foo<T = undefined> = {
otherFields: string
} & ([T] extends [undefined] ? {} : {
bar: T
})
let x: Foo<undefined> = {
otherFields: ""
}
let x2: Foo<string> = {
otherFields: "",
bar: ""
}
Upvotes: 2
Reputation: 3498
You can model it with two interfaces
interface FooBase {
// all expext bar
}
interface Foo<T> extends FooBase {
bar: T
}
this way the interface FooBase
contains every thing that that is always requiered and Foo
only conatins bar
but also enforces every thing that is declared by FooBase
.
Upvotes: 1