How to make an interface so that when T is passed, a is typed T, and when it's not passed, a can be optional (a missing property), for instance:
interface A<T = void> {
a: T
}
const a1: A<string> = { a: 'a' } // ๐ No error, good
const a2: A = {}
// ๐ Should not throw
// "Property 'a' is missing in type '{}' but required in type 'A<void>'.ts(2741)"
The only problem with the following approach is that a can't be missed from the object:
interface A<T = void> {
a: T extends void ? undefined : T
}
const a3: A = {}
// ๐ TS throws
// "Property 'a' is missing in type '{}' but required in type 'A<void>'. ts(2741)"
Why not have undefined as default type for T?
Otherwise, you can have conditional types:
interface A<T = void> {
a: T extends void ? undefined : T
}
To avoid having a required property with a type of undefined and remove the property completely, try using types instead:
type A<T = void> = T extends void ? Record<string, never> : { a: T }
... where Record<string, never> is a fancy way of denoting an empty object (don't use {}, which means โany non-nullish valueโ, and would thus accept also e.g. a string). If you then need additional properties that are always there in addition to a, you can write stuff like:
type A<T = void> = T extends void ? Record<string, never> : { a: T } & { b: number }
^^^^^^^^^^^^^^^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With